aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author_ov4 <ov4@ov4.org>2026-10-17 15:58:49 +0000
committer_ov4 <ov4@ov4.org>2026-10-17 15:58:49 +0000
commit44e3b4e38808072ac9e605ab5a216ae54db8c5e4 (patch)
tree405cf75a3c71125ce7580a8cd8e12352f203a07f
parent567d1c932284bdd53c60937ff6f4ce4a63d104bf (diff)
test(extern): call extern "C" functions from a user C++ object
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
-rw-r--r--tests/i/extern-cc-object/case.json5
-rw-r--r--tests/i/extern-cc-object/expected.txt6
-rw-r--r--tests/i/extern-cc-object/lib.cc25
-rw-r--r--tests/i/extern-cc-object/notes.md8
-rw-r--r--tests/i/extern-cc-object/program.cps13
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")