diff options
| author | _ov4 <ov4@ov4.org> | 2026-10-17 15:58:49 +0000 |
|---|---|---|
| committer | _ov4 <ov4@ov4.org> | 2026-10-17 15:58:49 +0000 |
| commit | 44e3b4e38808072ac9e605ab5a216ae54db8c5e4 (patch) | |
| tree | 405cf75a3c71125ce7580a8cd8e12352f203a07f /tests | |
| parent | 567d1c932284bdd53c60937ff6f4ce4a63d104bf (diff) | |
test(extern): call extern "C" functions from a user C++ object
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Diffstat (limited to 'tests')
| -rw-r--r-- | tests/i/extern-cc-object/case.json | 5 | ||||
| -rw-r--r-- | tests/i/extern-cc-object/expected.txt | 6 | ||||
| -rw-r--r-- | tests/i/extern-cc-object/lib.cc | 25 | ||||
| -rw-r--r-- | tests/i/extern-cc-object/notes.md | 8 | ||||
| -rw-r--r-- | tests/i/extern-cc-object/program.cps | 13 |
5 files changed, 57 insertions, 0 deletions
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 <typename T> +struct Accumulator { + T total; + constexpr Accumulator() : total(100) {} + T add(T v) { total += v; return total; } +}; +Accumulator<int> 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") |
