Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
17d1b03
dasClangBind: regen bindings for libclang 22.1.5, enable on mingw CI
borisbat May 24, 2026
5399dbb
dasClangBind: fix CI find_package + guard install() on empty DLL list
borisbat May 24, 2026
a7eed55
sqlite_linq: expression keys in _group_by + PR #2845 review fixes
borisbat May 24, 2026
96ac474
dasClangBind CI: add clang-22 apt package for ClangConfig.cmake
borisbat May 24, 2026
c4312eb
Merge pull request #2847 from GaijinEntertainment/bbatkin/sqlite-linq…
borisbat May 24, 2026
dd7fa56
dasClangBind CI: disable on linux (libLLVM-22 collision with dasLLVM)
borisbat May 24, 2026
62336a4
linq_fold: plan_decs_join + LinqJoin auto-typed result lambda
borisbat May 24, 2026
2ba9724
benchmarks/sql/results.md: refresh per living-doc policy
borisbat May 24, 2026
7e0cadf
infer: hoist per-module visibility out of overload resolution inner l…
borisbat May 24, 2026
891f56f
infer: lazy 2-flag subtree cache for TypeDecl::findAlias
borisbat May 24, 2026
b7b7513
mingw CI: install git in msys2 shell for self-binder diff check
borisbat May 24, 2026
0a2da40
Merge pull request #2848 from GaijinEntertainment/bbatkin/decs-join-lane
borisbat May 24, 2026
9f70413
gitattributes: pin dasClangBind generated files to LF
borisbat May 24, 2026
be65403
PR #2849 Copilot: short-circuit computeAliasCache on already-valid nodes
borisbat May 24, 2026
e2c1dbf
mingw CI: drop diff-check from self-binder; verify runs only
borisbat May 24, 2026
cc6ad7e
Merge pull request #2849 from GaijinEntertainment/bbatkin/infer-overl…
borisbat May 24, 2026
741c4be
Merge pull request #2846 from GaijinEntertainment/bbatkin/libclang-22…
borisbat May 24, 2026
3367ade
cbind_boost: normalize PARSE_FILE_PREFIX so prefix-strip survives bac…
borisbat May 24, 2026
71febd3
Merge pull request #2850 from GaijinEntertainment/bbatkin/cbind-strip…
borisbat May 24, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,11 @@ daslib/_aot_generated/*.cpp binary

# Shell scripts must keep LF endings even when checked out under autocrlf=true.
*.sh text eol=lf

# dasClangBind generated bindings: emit LF on every platform. The mingw
# CI worker re-runs bind_clangbind.das to detect regen drift; without
# eol=lf, autocrlf-true on the Windows runner checks out CRLF and the
# regen (which writes LF) reports every line as changed.
modules/dasClangBind/src/*.cpp text eol=lf
modules/dasClangBind/src/*.h text eol=lf
modules/dasClangBind/src/*.inc text eol=lf
29 changes: 25 additions & 4 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -482,9 +482,9 @@ jobs:
# (windows-latest-fat), separate top-level job so mingw churn doesn't risk
# the much-larger MSVC entries.
#
# dasClangBind stays disabled here — pinned to libclang 16.0.6 (find_package
# strict version), which the msys2 clang64 sysroot doesn't ship. Tracked
# separately as the bind_clangbind regen followup.
# dasClangBind is enabled here — find_package(Clang 22.1) matches msys2's
# libclang 22.1.x and POST_BUILD copies the libclang+libLLVM+libc++ chain
# next to daslang.exe so the .shared_module dlopen resolves at runtime.
###########################################################
needs: pre_job
if: needs.pre_job.outputs.should_skip != 'true'
Expand All @@ -509,6 +509,7 @@ jobs:
mingw-w64-clang-x86_64-openssl
mingw-w64-clang-x86_64-glfw
bison
git

- name: "Build: Daslang (clang-mingw64)"
run: |
Expand All @@ -518,7 +519,7 @@ jobs:
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_C_COMPILER=clang \
-DCMAKE_CXX_COMPILER=clang++ \
-DDAS_CLANG_BIND_DISABLED=ON \
-DDAS_CLANG_BIND_DISABLED=OFF \
-DDAS_LLVM_DISABLED=OFF
cmake --build ./build-mingw --parallel

Expand Down Expand Up @@ -548,3 +549,23 @@ jobs:
cd bin
./test_aot -use-aot _dasroot_/dastest/dastest.das -- --use-aot --color --failures-only --timeout 900 --test ../tests

# bind_clangbind self-binder lives here (not on linux extended_checks)
# because dasClangBind on linux pulls libclang.so → libLLVM-22.so.1,
# which collides with dasLLVM in the same process (shared pass
# registry, double-init breaks JIT). msys2 clang64 ships libclang as
# a separate SO chain, and the mingw worker doesn't exercise JIT-uses-
# dasClangBind paths, so they coexist cleanly.
#
# TODO: bind_llvm.das self-binder doesn't run on mingw — libclang as
# library doesn't find <cstddef> via msys2's libcxx auto-detection.
# Needs explicit -resource-dir / -isystem injection. Tracked as a
# follow-up; we lose master's previous bind_llvm.das CI coverage in
# the meantime.
- name: "Run self-binder (bind_clangbind.das)"
run: |
set -eux
CLANG_INCLUDE="$(cygpath -w "${MSYSTEM_PREFIX}/include")"
./bin/daslang.exe modules/dasClangBind/bind/bind_clangbind.das -- --clang_path "${CLANG_INCLUDE}/"
git diff --exit-code -- modules/dasClangBind/src/ \
|| (echo "ERROR: dasClangBind generated files are out of date. Run './bin/daslang modules/dasClangBind/bind/bind_clangbind.das -- --clang_path <libclang-include-path>' locally and commit the result." && exit 1)

31 changes: 11 additions & 20 deletions .github/workflows/extended_checks.yml
Original file line number Diff line number Diff line change
Expand Up @@ -109,10 +109,6 @@ jobs:
libxcursor-dev \
libxinerama-dev \
libxi-dev \
libclang-16-dev \
llvm-16-dev \
clang-16 \
libclang-22-dev \
llvm-22-dev
;;
esac
Expand All @@ -138,10 +134,17 @@ jobs:
;;
linux)
echo "BIN=./bin" >> $GITHUB_ENV
# dasClangBind stays OFF here — its libclang.so pulls in
# libLLVM-22.so.1 which collides with dasLLVM's own use of
# the same .so (shared LLVM pass registry → double init,
# breaks dasbind_example JIT-to-exe). dasClangBind is built
# and self-binder-checked on the mingw worker (build.yml)
# where it links against msys2's libclang and there is no
# dasLLVM in the same process.
CC=clang CXX=clang++ cmake --no-warn-unused-cli -B./build \
-DCMAKE_BUILD_TYPE:STRING=Release \
-DCMAKE_OSX_ARCHITECTURES="${{ matrix.architecture_string }}" \
-DDAS_CLANG_BIND_DISABLED=OFF \
-DDAS_CLANG_BIND_DISABLED=ON \
-DDAS_GLFW_DISABLED=OFF \
-G "${{ matrix.cmake_generator }}" $ACTIVE_MODULES
cmake --build ./build --config Release --target daslang daslang_static
Expand Down Expand Up @@ -252,21 +255,9 @@ jobs:
set -eux
$BIN/daslang _dasroot_/dastest/dastest.das -- --color --failures-only --test ./utils/mcp/test_tools.das

- name: "Run self-binder (bind_clangbind.das)"
if: matrix.target == 'linux'
run: |
set -eux
$BIN/daslang modules/dasClangBind/bind/bind_clangbind.das -- --clang_path /usr/lib/llvm-16/include/
git diff --exit-code -- modules/dasClangBind/src/ \
|| (echo "ERROR: dasClangBind generated files are out of date. Run './bin/daslang modules/dasClangBind/bind/bind_clangbind.das -- --clang_path <libclang-include-path>' locally and commit the result." && exit 1)

- name: "Run self-binder (bind_llvm.das)"
if: matrix.target == 'linux'
run: |
set -eux
$BIN/daslang modules/dasClangBind/bind/bind_llvm.das -- --input /usr/lib/llvm-22/include
git diff --exit-code -- modules/dasLLVM/bindings/ \
|| (echo "ERROR: dasLLVM generated bindings are out of date. Run './bin/daslang modules/dasClangBind/bind/bind_llvm.das -- --input <llvm-c-include-path>' locally and commit the result." && exit 1)
# Self-binders for dasClangBind + dasLLVM bindings live on the mingw
# worker (build.yml build_windows_mingw) — see comment on the linux
# build step above for why dasClangBind can't be enabled here.

- name: "Install dasImgui (daspkg)"
run: |
Expand Down
27 changes: 27 additions & 0 deletions benchmarks/sql/_common.das
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,12 @@ struct public DecsCar {
dealer_id : int
}

[decs_template(prefix = "dealer_")]
struct public DecsDealer {
id : int
name : string
}

def public fixture_decs(n : int) {
restart()
create_entities(n) $(eid : EntityId; i : int; var cmp : ComponentMap) {
Expand All @@ -102,6 +108,27 @@ def public fixture_decs(n : int) {
}
}

// Cars + Dealers together for the decs join lane. Both archetypes co-exist in the same decs world; plan_decs_join builds an in-query hash from the smaller side (dealers) then walks the larger side (cars).
def public fixture_decs_cars_and_dealers(n : int) {
restart()
create_entities(n) $(eid : EntityId; i : int; var cmp : ComponentMap) {
apply_decs_template(cmp, DecsCar(
id = i + 1,
name = "Car{i}",
price = (i * 37) % 1000,
brand = i % BRAND_COUNT,
year = 2010 + (i * 7) % 16,
dealer_id = (i % DEALER_COUNT) + 1
))
}
create_entities(DEALER_COUNT) $(eid : EntityId; i : int; var cmp : ComponentMap) {
apply_decs_template(cmp, DecsDealer(
id = i + 1,
name = "Dealer{i}"
))
}
}

// Same fixture as fixture_decs, but returns the eid of the n/2-th entity for indexed-lookup benches.
// The decs O(1) lookup path keys on EntityId (not the Car.id column), so the bench needs an actual eid
// captured at creation time. fixture_decs has no return so call sites can't reuse it for this.
Expand Down
35 changes: 27 additions & 8 deletions benchmarks/sql/groupby_select_sum.das
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,28 @@ options persistent_heap

require _common public

// _select(c => c.price) |> _group_by(price % 100) |> _select((K=key, S=sum)).
// SQL omitted: sqlite_linq's `_group_by` requires `_.Field` or a tuple of `_.Field`s.
// The expression key (`_ % 100`) is rejected. [Follow-up TODO 2026-05-23: error[50503]
// `_sql: _group_by: key must be \`_.Field\` or a tuple of \`_.Field\`s; got: (_ % 100)`
// — would need expression-key support in sqlite_linq lowering.]
// Array vs Decs is the headline comparison. Splice (PR-B) fuses the upstream Car→price
// projection into an intermediate var bind so the key + sum acc reference the projected
// int (no per-element Car re-access).
// _group_by(price % 100) |> _select((K = key, S = sum(price))).
// SQL: `SELECT (price % 100), SUM(price) FROM Cars GROUP BY (price % 100)` — exercises
// sqlite_linq's expression-key support in _group_by (PR S2). The m1 form uses
// `_group_by(_.price % 100)` + explicit inner select inside SUM (the shape the
// grouped-aggregate dispatch recognises); the m3f/m4 forms keep their splice-friendly
// `_select(_.price) |> _group_by(_ % 100) |> _select((K, S=_._1 |> sum()))` pattern,
// which fuses the upstream Car→price projection into an intermediate var bind.

def run_m1(b : B?; n : int) {
with_sqlite(":memory:") $(db) {
fixture_db(db, n)
b |> run("m1_sql/{n}", n) {
let groups <- _sql(db |> select_from(type<Car>)
|> _group_by(_.price % 100)
|> _select((K = _._0, S = _._1 |> select($(c : Car) => c.price) |> sum())))
b |> accept(groups)
if (empty(groups)) {
b->failNow()
}
}
}
}

def run_m3f(b : B?; n : int) {
let arr <- fixture_array(n)
Expand Down Expand Up @@ -42,6 +56,11 @@ def run_m4(b : B?; n : int) {
}
}

[benchmark]
def groupby_select_sum_m1(b : B?) {
run_m1(b, 100000)
}

[benchmark]
def groupby_select_sum_m3f(b : B?) {
run_m3f(b, 100000)
Expand Down
28 changes: 24 additions & 4 deletions benchmarks/sql/join_count.das
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,11 @@ require _common public
// SQL lane works via `_sql(... |> _join(db |> select_from(type<Dealer>), ...))`
// — the projection must be a named-tuple (positional tuples like `(c.name, d.name)`
// are rejected by `_sql`'s _select shape check; use `(CarName=..., DealerName=...)`).
// The Decs lane is absent — `_join` doesn't lower onto the archetype walk, and
// faithfully porting cross-archetype lookup would need a Dealer decs template +
// hash-by-id index. [Follow-up TODO 2026-05-23: decs join / cross-archetype lookup
// machinery — see plan_join in linq_fold.das, currently only handles iterator/array.]
// Decs lane: plan_decs_join (linq_fold.das) builds a hash from the smaller side
// (dealers) inside one `for_each_archetype` pass, then walks the larger side
// (cars) and probes — same algorithm as `join_impl` in linq.das (line 1674).
// Auto-typed result lambda (`$(l,r)=>...`) skips the verbose tuple type spelling
// over decs sources.

def run_m1(b : B?; n : int) {
with_sqlite(":memory:") $(db) {
Expand Down Expand Up @@ -43,6 +44,20 @@ def run_m3f(b : B?; n : int) {
}
}

def run_m4(b : B?; n : int) {
fixture_decs_cars_and_dealers(n)
b |> run("m4_decs_fold/{n}", n) {
let c = _fold(from_decs_template(type<DecsCar>) |> _join(from_decs_template(type<DecsDealer>),
$(l, r) => l.dealer_id == r.id,
$(l, r) => (CarName = l.name, DealerName = r.name))
|> count())
b |> accept(c)
if (c == 0) {
b->failNow()
}
}
}

[benchmark]
def join_count_m1(b : B?) {
run_m1(b, 100000)
Expand All @@ -52,3 +67,8 @@ def join_count_m1(b : B?) {
def join_count_m3f(b : B?) {
run_m3f(b, 100000)
}

[benchmark]
def join_count_m4(b : B?) {
run_m4(b, 100000)
}
Loading
Loading