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/kscan.h>
54 #include <zephyr/drivers/led.h>
55 #include <zephyr/drivers/led_strip.h>
56 #include <zephyr/drivers/lora.h>
57 #include <zephyr/drivers/mbox.h>
58 #include <zephyr/drivers/mdio.h>
59 #include <zephyr/drivers/mipi_dsi.h>
60 #include <zephyr/drivers/peci.h>
61 /* drivers/pinctrl.h requires SoC specific header */
62 #include <zephyr/drivers/pm_cpu_ops.h>
63 #include <zephyr/drivers/ps2.h>
64 #include <zephyr/drivers/ptp_clock.h>
65 #include <zephyr/drivers/pwm.h>
66 #include <zephyr/drivers/regulator.h>
67 /* drivers/reset.h conflicts with assert() for certain platforms */
68 #include <zephyr/drivers/sdhc.h>
69 #include <zephyr/drivers/sensor.h>
70 #include <zephyr/drivers/spi_emul.h>
71 #include <zephyr/drivers/spi.h>
72 #include <zephyr/drivers/syscon.h>
73 #include <zephyr/drivers/uart_pipe.h>
74 #include <zephyr/drivers/uart.h>
75 #include <zephyr/usb/usb_device.h>
76 #include <zephyr/usb/class/usb_hid.h>
77 #include <zephyr/drivers/video-controls.h>
78 #include <zephyr/drivers/video.h>
79 #include <zephyr/drivers/watchdog.h>
80 
81 /* Add RTIO headers to make sure they're CXX compatible */
82 #include <zephyr/rtio/rtio.h>
83 #include <zephyr/sys/spsc_lockfree.h>
84 #include <zephyr/sys/mpsc_lockfree.h>
85 
86 #include <zephyr/ztest.h>
87 
88 class foo_class {
89 public:
foo_class(int foo)90 	foo_class(int foo) : foo(foo) {}
get_foo() const91 	int get_foo() const { return foo;}
92 private:
93 	int foo;
94 };
95 
96 struct foo {
97 	int v1;
98 };
99 /* Check that BUILD_ASSERT compiles. */
100 BUILD_ASSERT(sizeof(foo) == sizeof(int));
101 
102 __maybe_unused static struct foo foos[5];
103 /* Check that ARRAY_SIZE compiles. */
104 BUILD_ASSERT(ARRAY_SIZE(foos) == 5, "expected 5 elements");
105 
106 /* Check that SYS_INIT() compiles. */
test_init(void)107 static int test_init(void)
108 {
109 	return 0;
110 }
111 
112 SYS_INIT(test_init, APPLICATION, CONFIG_APPLICATION_INIT_PRIORITY);
113 
114 /* Check that global static object constructors are called. */
115 foo_class static_foo(12345678);
116 
ZTEST(cxx_tests,test_global_static_ctor)117 ZTEST(cxx_tests, test_global_static_ctor)
118 {
119 	zassert_equal(static_foo.get_foo(), 12345678);
120 }
121 
122 /*
123  * Check that dynamic memory allocation (usually, the C library heap) is
124  * functional when the global static object constructors are called.
125  */
126 foo_class *static_init_dynamic_foo = new foo_class(87654321);
127 
ZTEST(cxx_tests,test_global_static_ctor_dynmem)128 ZTEST(cxx_tests, test_global_static_ctor_dynmem)
129 {
130 	zassert_equal(static_init_dynamic_foo->get_foo(), 87654321);
131 }
132 
ZTEST(cxx_tests,test_new_delete)133 ZTEST(cxx_tests, test_new_delete)
134 {
135 	foo_class *test_foo = new foo_class(10);
136 	zassert_equal(test_foo->get_foo(), 10);
137 	delete test_foo;
138 }
139 ZTEST_SUITE(cxx_tests, NULL, NULL, NULL, NULL, NULL);
140 
141 /*
142  * Unused macros are parsed but not actually compiled. So, even with all their NULL
143  * arguments these one-liners add significant C++ coverage. For instance this actually
144  * compiles some of the macros in zephyr/device.h in C++.
145  *
146  * DEVICE_DEFINE(dev_id, name, * init_fn, pm, data, config, level, prio, api)
147  */
148 DEVICE_DT_DEFINE(DT_NODELABEL(test_dev1_dfr), NULL, NULL, NULL, NULL, POST_KERNEL, 33, NULL);
149 
fake_pm_action(const struct device * dev,enum pm_device_action pm_action)150 static int fake_pm_action(const struct device *dev,
151 		enum pm_device_action pm_action) { return -1; }
152 PM_DEVICE_DT_DEFINE(DT_NODELABEL(test_dev0_boot), fake_pm_action);
153 
154 DEVICE_DT_DEFINE(DT_NODELABEL(test_dev0_boot), NULL,
155 		 PM_DEVICE_DT_GET(DT_NODELABEL(test_dev0_boot)), NULL, NULL, POST_KERNEL, 34, NULL);
156