1 /*
2  * Copyright (c) 2018 Google LLC.
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 /*
8  * This is mainly a parse test that verifies that Zephyr header files
9  * compile in C++ mode.
10  */
11 
12 #include <string.h>
13 #include <zephyr/types.h>
14 #include <stdbool.h>
15 
16 #include <zephyr/init.h>
17 #include <zephyr/device.h>
18 #include <zephyr/pm/device.h>
19 #include <zephyr/kernel.h>
20 #include <zephyr/net_buf.h>
21 #include <zephyr/sys/crc.h>
22 #include <zephyr/sys/crc.h>
23 
24 #include <zephyr/drivers/adc.h>
25 #include <zephyr/drivers/bbram.h>
26 #include <zephyr/drivers/cache.h>
27 #include <zephyr/drivers/can.h>
28 #include <zephyr/drivers/can/transceiver.h>
29 #include <zephyr/drivers/clock_control.h>
30 #include <zephyr/drivers/coredump.h>
31 #include <zephyr/drivers/counter.h>
32 #include <zephyr/drivers/dac.h>
33 #include <zephyr/drivers/dai.h>
34 #include <zephyr/drivers/disk.h>
35 #include <zephyr/drivers/display.h>
36 #include <zephyr/drivers/dma.h>
37 #include <zephyr/drivers/edac.h>
38 #include <zephyr/drivers/eeprom.h>
39 #include <zephyr/drivers/emul.h>
40 #include <zephyr/drivers/entropy.h>
41 #include <zephyr/drivers/espi_emul.h>
42 #include <zephyr/drivers/espi.h>
43 /* drivers/espi_saf.h requires SoC specific header */
44 #include <zephyr/drivers/flash.h>
45 #include <zephyr/drivers/fpga.h>
46 #include <zephyr/drivers/gpio.h>
47 #include <zephyr/drivers/hwinfo.h>
48 #include <zephyr/drivers/i2c_emul.h>
49 #include <zephyr/drivers/i2c.h>
50 #include <zephyr/drivers/i2s.h>
51 #include <zephyr/drivers/i3c.h>
52 #include <zephyr/drivers/ipm.h>
53 #include <zephyr/drivers/led.h>
54 #include <zephyr/drivers/led_strip.h>
55 #include <zephyr/drivers/lora.h>
56 #include <zephyr/drivers/mbox.h>
57 #include <zephyr/drivers/mdio.h>
58 #include <zephyr/drivers/mipi_dsi.h>
59 #include <zephyr/drivers/peci.h>
60 /* drivers/pinctrl.h requires SoC specific header */
61 #include <zephyr/drivers/pm_cpu_ops.h>
62 #include <zephyr/drivers/ps2.h>
63 #include <zephyr/drivers/ptp_clock.h>
64 #include <zephyr/drivers/pwm.h>
65 #include <zephyr/drivers/regulator.h>
66 /* drivers/reset.h conflicts with assert() for certain platforms */
67 #include <zephyr/drivers/sdhc.h>
68 #include <zephyr/drivers/sensor.h>
69 #include <zephyr/drivers/spi_emul.h>
70 #include <zephyr/drivers/spi.h>
71 #include <zephyr/drivers/syscon.h>
72 #include <zephyr/drivers/uart_pipe.h>
73 #include <zephyr/drivers/uart.h>
74 #include <zephyr/usb/usb_device.h>
75 #include <zephyr/usb/class/usb_hid.h>
76 #include <zephyr/drivers/video-controls.h>
77 #include <zephyr/drivers/video.h>
78 #include <zephyr/drivers/watchdog.h>
79 
80 /* Add RTIO headers to make sure they're CXX compatible */
81 #include <zephyr/rtio/rtio.h>
82 #include <zephyr/sys/spsc_lockfree.h>
83 #include <zephyr/sys/mpsc_lockfree.h>
84 
85 #include <zephyr/ztest.h>
86 
87 class foo_class {
88 public:
foo_class(int foo)89 	foo_class(int foo) : foo(foo) {}
get_foo() const90 	int get_foo() const { return foo;}
91 private:
92 	int foo;
93 };
94 
95 struct foo {
96 	int v1;
97 };
98 /* Check that BUILD_ASSERT compiles. */
99 BUILD_ASSERT(sizeof(foo) == sizeof(int));
100 
101 __maybe_unused static struct foo foos[5];
102 /* Check that ARRAY_SIZE compiles. */
103 BUILD_ASSERT(ARRAY_SIZE(foos) == 5, "expected 5 elements");
104 
105 /* Check that SYS_INIT() compiles. */
test_init(void)106 static int test_init(void)
107 {
108 	return 0;
109 }
110 
111 SYS_INIT(test_init, APPLICATION, CONFIG_APPLICATION_INIT_PRIORITY);
112 
113 /* Check that global static object constructors are called. */
114 foo_class static_foo(12345678);
115 
ZTEST(cxx_tests,test_global_static_ctor)116 ZTEST(cxx_tests, test_global_static_ctor)
117 {
118 	zassert_equal(static_foo.get_foo(), 12345678);
119 }
120 
121 /*
122  * Check that dynamic memory allocation (usually, the C library heap) is
123  * functional when the global static object constructors are called.
124  */
125 foo_class *static_init_dynamic_foo = new foo_class(87654321);
126 
ZTEST(cxx_tests,test_global_static_ctor_dynmem)127 ZTEST(cxx_tests, test_global_static_ctor_dynmem)
128 {
129 	zassert_equal(static_init_dynamic_foo->get_foo(), 87654321);
130 }
131 
ZTEST(cxx_tests,test_new_delete)132 ZTEST(cxx_tests, test_new_delete)
133 {
134 	foo_class *test_foo = new foo_class(10);
135 	zassert_equal(test_foo->get_foo(), 10);
136 	delete test_foo;
137 }
138 ZTEST_SUITE(cxx_tests, NULL, NULL, NULL, NULL, NULL);
139 
140 /*
141  * Unused macros are parsed but not actually compiled. So, even with all their NULL
142  * arguments these one-liners add significant C++ coverage. For instance this actually
143  * compiles some of the macros in zephyr/device.h in C++.
144  *
145  * DEVICE_DEFINE(dev_id, name, * init_fn, pm, data, config, level, prio, api)
146  */
147 DEVICE_DT_DEFINE(DT_NODELABEL(test_dev1_dfr), NULL, NULL, NULL, NULL, POST_KERNEL, 33, NULL);
148 
fake_pm_action(const struct device * dev,enum pm_device_action pm_action)149 static int fake_pm_action(const struct device *dev,
150 		enum pm_device_action pm_action) { return -1; }
151 PM_DEVICE_DT_DEFINE(DT_NODELABEL(test_dev0_boot), fake_pm_action);
152 
153 DEVICE_DT_DEFINE(DT_NODELABEL(test_dev0_boot), NULL,
154 		 PM_DEVICE_DT_GET(DT_NODELABEL(test_dev0_boot)), NULL, NULL, POST_KERNEL, 34, NULL);
155