From 44e3b4e38808072ac9e605ab5a216ae54db8c5e4 Mon Sep 17 00:00:00 2001 From: _ov4 Date: Sat, 17 Oct 2026 15:58:49 +0000 Subject: test(extern): call extern "C" functions from a user C++ object Co-Authored-By: Claude Sonnet 5.5 --- tests/i/extern-cc-object/case.json | 5 +++++ tests/i/extern-cc-object/expected.txt | 6 ++++++ tests/i/extern-cc-object/lib.cc | 25 +++++++++++++++++++++++++ tests/i/extern-cc-object/notes.md | 8 ++++++++ tests/i/extern-cc-object/program.cps | 13 +++++++++++++ 5 files changed, 57 insertions(+) create mode 100644 tests/i/extern-cc-object/case.json create mode 100644 tests/i/extern-cc-object/expected.txt create mode 100644 tests/i/extern-cc-object/lib.cc create mode 100644 tests/i/extern-cc-object/notes.md create mode 100644 tests/i/extern-cc-object/program.cps diff --git a/tests/i/extern-cc-object/case.json b/tests/i/extern-cc-object/case.json new file mode 100644 index 0000000..54b74bf --- /dev/null +++ b/tests/i/extern-cc-object/case.json @@ -0,0 +1,5 @@ +{ + "objects": [ + {"source": "lib.cc", "output": "lib.o"} + ] +} diff --git a/tests/i/extern-cc-object/expected.txt b/tests/i/extern-cc-object/expected.txt new file mode 100644 index 0000000..cb8b011 --- /dev/null +++ b/tests/i/extern-cc-object/expected.txt @@ -0,0 +1,6 @@ +100 +105 +112 +112 +5 +hi from lib.cc diff --git a/tests/i/extern-cc-object/lib.cc b/tests/i/extern-cc-object/lib.cc new file mode 100644 index 0000000..cbf5983 --- /dev/null +++ b/tests/i/extern-cc-object/lib.cc @@ -0,0 +1,25 @@ +// No C++ runtime library: only C++ language features, so unmangled names are the point. +namespace { +template +struct Accumulator { + T total; + constexpr Accumulator() : total(100) {} + T add(T v) { total += v; return total; } +}; +Accumulator acc; + +unsigned length_of(const char *s) { + unsigned n = 0; + while (s[n]) ++n; + return n; +} +} + +extern "C" int puts(const char *); + +extern "C" { +int cc_sum(void) { return acc.total; } +int cc_add(int v) { return acc.add(v); } +int cc_text_length(const char *s) { return (int)length_of(s) + 2; } +void cc_say(const char *s) { puts(s); } +} diff --git a/tests/i/extern-cc-object/notes.md b/tests/i/extern-cc-object/notes.md new file mode 100644 index 0000000..8d9611f --- /dev/null +++ b/tests/i/extern-cc-object/notes.md @@ -0,0 +1,8 @@ +# extern-cc-object + +Human review: pending. Expected output was independently traced by AI, not captured from cpsc. + +Basis: compiler extension (EXTERN "C", INCLUDE_OBJ of a user object); `lib.cc` is built with the host C++ compiler, exports unmangled `extern "C"` symbols and avoids the C++ runtime library (JIT does not load libstdc++; native would). + +Trace: a C++ template object starts at 100. cc_sum()=100; cc_add(5)=105; cc_add(7)=112; cc_sum()=112. cc_text_length("abc") counts 3 characters plus 2, giving 5. cc_say calls the C library puts, linked through INCLUDE_OBJ "__libc". + diff --git a/tests/i/extern-cc-object/program.cps b/tests/i/extern-cc-object/program.cps new file mode 100644 index 0000000..6e09f77 --- /dev/null +++ b/tests/i/extern-cc-object/program.cps @@ -0,0 +1,13 @@ +// extern "C" symbols from a C++ object; the C++ names would otherwise be mangled. +INCLUDE_OBJ "lib.o" +INCLUDE_OBJ "__libc" +EXTERN "C" EXTERN_FUNCTION cc_sum() RETURNS C_INT +EXTERN "C" EXTERN_FUNCTION cc_add(C_INT) RETURNS C_INT +EXTERN "C" EXTERN_FUNCTION cc_text_length(C_STRING) RETURNS C_INT +EXTERN "C" EXTERN_PROCEDURE cc_say(C_STRING) +OUTPUT cc_sum() +OUTPUT cc_add((C_INT)5) +OUTPUT cc_add((C_INT)7) +OUTPUT cc_sum() +OUTPUT cc_text_length((C_STRING)"abc") +CALL cc_say((C_STRING)"hi from lib.cc") -- cgit v1.3.1-4-g156e