1f08c3bdfSopenharmony_ci#ifndef EXPRESSION_H
2f08c3bdfSopenharmony_ci#define EXPRESSION_H
3f08c3bdfSopenharmony_ci/*
4f08c3bdfSopenharmony_ci * sparse/expression.h
5f08c3bdfSopenharmony_ci *
6f08c3bdfSopenharmony_ci * Copyright (C) 2003 Transmeta Corp.
7f08c3bdfSopenharmony_ci *               2003 Linus Torvalds
8f08c3bdfSopenharmony_ci *
9f08c3bdfSopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a copy
10f08c3bdfSopenharmony_ci * of this software and associated documentation files (the "Software"), to deal
11f08c3bdfSopenharmony_ci * in the Software without restriction, including without limitation the rights
12f08c3bdfSopenharmony_ci * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13f08c3bdfSopenharmony_ci * copies of the Software, and to permit persons to whom the Software is
14f08c3bdfSopenharmony_ci * furnished to do so, subject to the following conditions:
15f08c3bdfSopenharmony_ci *
16f08c3bdfSopenharmony_ci * The above copyright notice and this permission notice shall be included in
17f08c3bdfSopenharmony_ci * all copies or substantial portions of the Software.
18f08c3bdfSopenharmony_ci *
19f08c3bdfSopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20f08c3bdfSopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21f08c3bdfSopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22f08c3bdfSopenharmony_ci * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23f08c3bdfSopenharmony_ci * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24f08c3bdfSopenharmony_ci * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25f08c3bdfSopenharmony_ci * THE SOFTWARE.
26f08c3bdfSopenharmony_ci *
27f08c3bdfSopenharmony_ci * Declarations and helper functions for expression parsing.
28f08c3bdfSopenharmony_ci */
29f08c3bdfSopenharmony_ci
30f08c3bdfSopenharmony_ci#include "allocate.h"
31f08c3bdfSopenharmony_ci#include "lib.h"
32f08c3bdfSopenharmony_ci#include "symbol.h"
33f08c3bdfSopenharmony_ci
34f08c3bdfSopenharmony_cistruct expression_list;
35f08c3bdfSopenharmony_ci
36f08c3bdfSopenharmony_cienum expression_type {
37f08c3bdfSopenharmony_ci	EXPR_VALUE = 1,
38f08c3bdfSopenharmony_ci	EXPR_STRING,
39f08c3bdfSopenharmony_ci	EXPR_SYMBOL,
40f08c3bdfSopenharmony_ci	EXPR_TYPE,
41f08c3bdfSopenharmony_ci	EXPR_BINOP,
42f08c3bdfSopenharmony_ci	EXPR_ASSIGNMENT,
43f08c3bdfSopenharmony_ci	EXPR_LOGICAL,
44f08c3bdfSopenharmony_ci	EXPR_DEREF,
45f08c3bdfSopenharmony_ci	EXPR_PREOP,
46f08c3bdfSopenharmony_ci	EXPR_POSTOP,
47f08c3bdfSopenharmony_ci	EXPR_CAST,
48f08c3bdfSopenharmony_ci	EXPR_FORCE_CAST,
49f08c3bdfSopenharmony_ci	EXPR_IMPLIED_CAST,
50f08c3bdfSopenharmony_ci	EXPR_SIZEOF,
51f08c3bdfSopenharmony_ci	EXPR_ALIGNOF,
52f08c3bdfSopenharmony_ci	EXPR_PTRSIZEOF,
53f08c3bdfSopenharmony_ci	EXPR_CONDITIONAL,
54f08c3bdfSopenharmony_ci	EXPR_SELECT,		// a "safe" conditional expression
55f08c3bdfSopenharmony_ci	EXPR_STATEMENT,
56f08c3bdfSopenharmony_ci	EXPR_CALL,
57f08c3bdfSopenharmony_ci	EXPR_COMMA,
58f08c3bdfSopenharmony_ci	EXPR_COMPARE,
59f08c3bdfSopenharmony_ci	EXPR_LABEL,
60f08c3bdfSopenharmony_ci	EXPR_INITIALIZER,	// initializer list
61f08c3bdfSopenharmony_ci	EXPR_IDENTIFIER,	// identifier in initializer
62f08c3bdfSopenharmony_ci	EXPR_INDEX,		// index in initializer
63f08c3bdfSopenharmony_ci	EXPR_POS,		// position in initializer
64f08c3bdfSopenharmony_ci	EXPR_FVALUE,
65f08c3bdfSopenharmony_ci	EXPR_SLICE,
66f08c3bdfSopenharmony_ci	EXPR_OFFSETOF,
67f08c3bdfSopenharmony_ci	EXPR_GENERIC,
68f08c3bdfSopenharmony_ci};
69f08c3bdfSopenharmony_ci
70f08c3bdfSopenharmony_ci
71f08c3bdfSopenharmony_ci/*
72f08c3bdfSopenharmony_ci * Flags for tracking the promotion of constness related attributes
73f08c3bdfSopenharmony_ci * from subexpressions to their parents.
74f08c3bdfSopenharmony_ci *
75f08c3bdfSopenharmony_ci * The flags are not independent as one might imply another.
76f08c3bdfSopenharmony_ci * The implications are as follows:
77f08c3bdfSopenharmony_ci * - CEF_INT, CEF_ENUM and
78f08c3bdfSopenharmony_ci *   CEF_CHAR imply CEF_ICE.
79f08c3bdfSopenharmony_ci *
80f08c3bdfSopenharmony_ci * Use the CEF_*_SET_MASK and CEF_*_CLEAR_MASK
81f08c3bdfSopenharmony_ci * helper macros defined below to set or clear one of these flags.
82f08c3bdfSopenharmony_ci */
83f08c3bdfSopenharmony_cienum constexpr_flag {
84f08c3bdfSopenharmony_ci	CEF_NONE = 0,
85f08c3bdfSopenharmony_ci	/*
86f08c3bdfSopenharmony_ci	 * A constant in the sense of [6.4.4]:
87f08c3bdfSopenharmony_ci	 * - Integer constant [6.4.4.1]
88f08c3bdfSopenharmony_ci	 * - Floating point constant [6.4.4.2]
89f08c3bdfSopenharmony_ci	 * - Enumeration constant [6.4.4.3]
90f08c3bdfSopenharmony_ci	 * - Character constant [6.4.4.4]
91f08c3bdfSopenharmony_ci	 */
92f08c3bdfSopenharmony_ci	CEF_INT = (1 << 0),
93f08c3bdfSopenharmony_ci	CEF_FLOAT = (1 << 1),
94f08c3bdfSopenharmony_ci	CEF_ENUM = (1 << 2),
95f08c3bdfSopenharmony_ci	CEF_CHAR = (1 << 3),
96f08c3bdfSopenharmony_ci
97f08c3bdfSopenharmony_ci	/*
98f08c3bdfSopenharmony_ci	 * A constant expression in the sense of [6.6]:
99f08c3bdfSopenharmony_ci	 * - integer constant expression [6.6(6)]
100f08c3bdfSopenharmony_ci	 * - arithmetic constant expression [6.6(8)]
101f08c3bdfSopenharmony_ci	 * - address constant [6.6(9)]
102f08c3bdfSopenharmony_ci	 */
103f08c3bdfSopenharmony_ci	CEF_ICE = (1 << 4),
104f08c3bdfSopenharmony_ci	CEF_ACE = (1 << 5),
105f08c3bdfSopenharmony_ci	CEF_ADDR = (1 << 6),
106f08c3bdfSopenharmony_ci
107f08c3bdfSopenharmony_ci	/* integer constant expression => arithmetic constant expression */
108f08c3bdfSopenharmony_ci	CEF_SET_ICE = (CEF_ICE | CEF_ACE),
109f08c3bdfSopenharmony_ci
110f08c3bdfSopenharmony_ci	/* integer constant => integer constant expression */
111f08c3bdfSopenharmony_ci	CEF_SET_INT = (CEF_INT | CEF_SET_ICE),
112f08c3bdfSopenharmony_ci
113f08c3bdfSopenharmony_ci	/* floating point constant => arithmetic constant expression */
114f08c3bdfSopenharmony_ci	CEF_SET_FLOAT = (CEF_FLOAT | CEF_ACE),
115f08c3bdfSopenharmony_ci
116f08c3bdfSopenharmony_ci	/* enumeration constant => integer constant expression */
117f08c3bdfSopenharmony_ci	CEF_SET_ENUM = (CEF_ENUM | CEF_SET_ICE),
118f08c3bdfSopenharmony_ci
119f08c3bdfSopenharmony_ci	/* character constant => integer constant expression */
120f08c3bdfSopenharmony_ci	CEF_SET_CHAR = (CEF_CHAR | CEF_SET_ICE),
121f08c3bdfSopenharmony_ci
122f08c3bdfSopenharmony_ci	/*
123f08c3bdfSopenharmony_ci	 * Remove any "Constant" [6.4.4] flag, but retain the "constant
124f08c3bdfSopenharmony_ci	 * expression" [6.6] flags.
125f08c3bdfSopenharmony_ci	 */
126f08c3bdfSopenharmony_ci	CEF_CONST_MASK = (CEF_INT | CEF_FLOAT | CEF_CHAR),
127f08c3bdfSopenharmony_ci
128f08c3bdfSopenharmony_ci	/*
129f08c3bdfSopenharmony_ci	 * not an integer constant expression => neither of integer,
130f08c3bdfSopenharmony_ci	 * enumeration and character constant
131f08c3bdfSopenharmony_ci	 */
132f08c3bdfSopenharmony_ci	CEF_CLR_ICE = (CEF_ICE | CEF_INT | CEF_ENUM | CEF_CHAR),
133f08c3bdfSopenharmony_ci};
134f08c3bdfSopenharmony_ci
135f08c3bdfSopenharmony_cienum {
136f08c3bdfSopenharmony_ci	Taint_comma = 1,
137f08c3bdfSopenharmony_ci}; /* for expr->taint */
138f08c3bdfSopenharmony_ci
139f08c3bdfSopenharmony_cistruct asm_operand {
140f08c3bdfSopenharmony_ci	struct ident *name;
141f08c3bdfSopenharmony_ci	struct expression *constraint;
142f08c3bdfSopenharmony_ci	struct expression *expr;
143f08c3bdfSopenharmony_ci	unsigned int is_assign:1;
144f08c3bdfSopenharmony_ci	unsigned int is_modify:1;
145f08c3bdfSopenharmony_ci	unsigned int is_earlyclobber:1;
146f08c3bdfSopenharmony_ci	unsigned int is_commutative:1;
147f08c3bdfSopenharmony_ci	unsigned int is_register:1;
148f08c3bdfSopenharmony_ci	unsigned int is_memory:1;
149f08c3bdfSopenharmony_ci};
150f08c3bdfSopenharmony_ci
151f08c3bdfSopenharmony_cistruct type_expression {
152f08c3bdfSopenharmony_ci	struct symbol *type;
153f08c3bdfSopenharmony_ci	struct expression *expr;
154f08c3bdfSopenharmony_ci	struct type_expression *next;
155f08c3bdfSopenharmony_ci};
156f08c3bdfSopenharmony_ci
157f08c3bdfSopenharmony_ciDECLARE_ALLOCATOR(type_expression);
158f08c3bdfSopenharmony_ci
159f08c3bdfSopenharmony_cistruct expression {
160f08c3bdfSopenharmony_ci	enum expression_type type:8;
161f08c3bdfSopenharmony_ci	unsigned flags:8;
162f08c3bdfSopenharmony_ci	unsigned zero_init:1;
163f08c3bdfSopenharmony_ci	int op;
164f08c3bdfSopenharmony_ci	struct position pos;
165f08c3bdfSopenharmony_ci	struct symbol *ctype;
166f08c3bdfSopenharmony_ci	union {
167f08c3bdfSopenharmony_ci		// EXPR_VALUE
168f08c3bdfSopenharmony_ci		struct {
169f08c3bdfSopenharmony_ci			unsigned long long value;
170f08c3bdfSopenharmony_ci			unsigned taint;
171f08c3bdfSopenharmony_ci		};
172f08c3bdfSopenharmony_ci
173f08c3bdfSopenharmony_ci		// EXPR_FVALUE
174f08c3bdfSopenharmony_ci		long double fvalue;
175f08c3bdfSopenharmony_ci
176f08c3bdfSopenharmony_ci		// EXPR_STRING
177f08c3bdfSopenharmony_ci		struct {
178f08c3bdfSopenharmony_ci			int wide;
179f08c3bdfSopenharmony_ci			struct string *string;
180f08c3bdfSopenharmony_ci		};
181f08c3bdfSopenharmony_ci
182f08c3bdfSopenharmony_ci		// EXPR_UNOP, EXPR_PREOP and EXPR_POSTOP
183f08c3bdfSopenharmony_ci		struct /* unop */ {
184f08c3bdfSopenharmony_ci			struct expression *unop;
185f08c3bdfSopenharmony_ci			unsigned long op_value;
186f08c3bdfSopenharmony_ci		};
187f08c3bdfSopenharmony_ci
188f08c3bdfSopenharmony_ci		// EXPR_SYMBOL, EXPR_TYPE
189f08c3bdfSopenharmony_ci		struct /* symbol_arg */ {
190f08c3bdfSopenharmony_ci			struct symbol *symbol;
191f08c3bdfSopenharmony_ci			struct ident *symbol_name;
192f08c3bdfSopenharmony_ci		};
193f08c3bdfSopenharmony_ci
194f08c3bdfSopenharmony_ci		// EXPR_STATEMENT
195f08c3bdfSopenharmony_ci		struct statement *statement;
196f08c3bdfSopenharmony_ci
197f08c3bdfSopenharmony_ci		// EXPR_BINOP, EXPR_COMMA, EXPR_COMPARE, EXPR_LOGICAL and EXPR_ASSIGNMENT
198f08c3bdfSopenharmony_ci		struct /* binop_arg */ {
199f08c3bdfSopenharmony_ci			struct expression *left, *right;
200f08c3bdfSopenharmony_ci		};
201f08c3bdfSopenharmony_ci		// EXPR_DEREF
202f08c3bdfSopenharmony_ci		struct /* deref_arg */ {
203f08c3bdfSopenharmony_ci			struct expression *deref;
204f08c3bdfSopenharmony_ci			struct ident *member;
205f08c3bdfSopenharmony_ci		};
206f08c3bdfSopenharmony_ci		// EXPR_SLICE
207f08c3bdfSopenharmony_ci		struct /* slice */ {
208f08c3bdfSopenharmony_ci			struct expression *base;
209f08c3bdfSopenharmony_ci			unsigned r_bitpos;
210f08c3bdfSopenharmony_ci		};
211f08c3bdfSopenharmony_ci		// EXPR_CAST, EXPR_FORCE_CAST, EXPR_IMPLIED_CAST,
212f08c3bdfSopenharmony_ci		// EXPR_SIZEOF, EXPR_ALIGNOF and EXPR_PTRSIZEOF
213f08c3bdfSopenharmony_ci		struct /* cast_arg */ {
214f08c3bdfSopenharmony_ci			struct symbol *cast_type;
215f08c3bdfSopenharmony_ci			struct expression *cast_expression;
216f08c3bdfSopenharmony_ci		};
217f08c3bdfSopenharmony_ci		// EXPR_CONDITIONAL
218f08c3bdfSopenharmony_ci		// EXPR_SELECT
219f08c3bdfSopenharmony_ci		struct /* conditional_expr */ {
220f08c3bdfSopenharmony_ci			struct expression *conditional, *cond_true, *cond_false;
221f08c3bdfSopenharmony_ci		};
222f08c3bdfSopenharmony_ci		// EXPR_CALL
223f08c3bdfSopenharmony_ci		struct /* call_expr */ {
224f08c3bdfSopenharmony_ci			struct expression *fn;
225f08c3bdfSopenharmony_ci			struct expression_list *args;
226f08c3bdfSopenharmony_ci		};
227f08c3bdfSopenharmony_ci		// EXPR_LABEL
228f08c3bdfSopenharmony_ci		struct /* label_expr */ {
229f08c3bdfSopenharmony_ci			struct symbol *label_symbol;
230f08c3bdfSopenharmony_ci		};
231f08c3bdfSopenharmony_ci		// EXPR_INITIALIZER
232f08c3bdfSopenharmony_ci		struct expression_list *expr_list;
233f08c3bdfSopenharmony_ci		// EXPR_IDENTIFIER
234f08c3bdfSopenharmony_ci		struct /* ident_expr */ {
235f08c3bdfSopenharmony_ci			int offset;
236f08c3bdfSopenharmony_ci			struct ident *expr_ident;
237f08c3bdfSopenharmony_ci			struct symbol *field;
238f08c3bdfSopenharmony_ci			struct expression *ident_expression;
239f08c3bdfSopenharmony_ci		};
240f08c3bdfSopenharmony_ci		// EXPR_INDEX
241f08c3bdfSopenharmony_ci		struct /* index_expr */ {
242f08c3bdfSopenharmony_ci			unsigned int idx_from, idx_to;
243f08c3bdfSopenharmony_ci			struct expression *idx_expression;
244f08c3bdfSopenharmony_ci		};
245f08c3bdfSopenharmony_ci		// EXPR_POS
246f08c3bdfSopenharmony_ci		struct /* initpos_expr */ {
247f08c3bdfSopenharmony_ci			unsigned int init_offset, init_nr;
248f08c3bdfSopenharmony_ci			struct expression *init_expr;
249f08c3bdfSopenharmony_ci		};
250f08c3bdfSopenharmony_ci		// EXPR_OFFSETOF
251f08c3bdfSopenharmony_ci		struct {
252f08c3bdfSopenharmony_ci			struct symbol *in;
253f08c3bdfSopenharmony_ci			struct expression *down;
254f08c3bdfSopenharmony_ci			union {
255f08c3bdfSopenharmony_ci				struct ident *ident;
256f08c3bdfSopenharmony_ci				struct expression *index;
257f08c3bdfSopenharmony_ci			};
258f08c3bdfSopenharmony_ci		};
259f08c3bdfSopenharmony_ci		// EXPR_GENERIC
260f08c3bdfSopenharmony_ci		struct {
261f08c3bdfSopenharmony_ci			struct expression *control;
262f08c3bdfSopenharmony_ci			struct expression *def;
263f08c3bdfSopenharmony_ci			struct type_expression *map;
264f08c3bdfSopenharmony_ci		};
265f08c3bdfSopenharmony_ci	};
266f08c3bdfSopenharmony_ci};
267f08c3bdfSopenharmony_ci
268f08c3bdfSopenharmony_ci///
269f08c3bdfSopenharmony_ci// Constant expression values
270f08c3bdfSopenharmony_ci// --------------------------
271f08c3bdfSopenharmony_ci
272f08c3bdfSopenharmony_ci///
273f08c3bdfSopenharmony_ci// test if an expression evaluates to the constant ``0``.
274f08c3bdfSopenharmony_ci// @return: ``1`` if @expr evaluate to ``0``,
275f08c3bdfSopenharmony_ci//	``0`` otherwise.
276f08c3bdfSopenharmony_ciint is_zero_constant(struct expression *expr);
277f08c3bdfSopenharmony_ci
278f08c3bdfSopenharmony_ci///
279f08c3bdfSopenharmony_ci// test the compile time truth value of an expression
280f08c3bdfSopenharmony_ci// @return:
281f08c3bdfSopenharmony_ci//	* ``-1`` if @expr is not constant,
282f08c3bdfSopenharmony_ci//	* ``0`` or ``1`` depending on the truth value of @expr.
283f08c3bdfSopenharmony_ciint expr_truth_value(struct expression *expr);
284f08c3bdfSopenharmony_ci
285f08c3bdfSopenharmony_cilong long get_expression_value(struct expression *);
286f08c3bdfSopenharmony_cilong long const_expression_value(struct expression *);
287f08c3bdfSopenharmony_cilong long get_expression_value_silent(struct expression *expr);
288f08c3bdfSopenharmony_ci
289f08c3bdfSopenharmony_ci/* Expression parsing */
290f08c3bdfSopenharmony_cistruct token *parse_expression(struct token *token, struct expression **tree);
291f08c3bdfSopenharmony_cistruct token *conditional_expression(struct token *token, struct expression **tree);
292f08c3bdfSopenharmony_cistruct token *primary_expression(struct token *token, struct expression **tree);
293f08c3bdfSopenharmony_cistruct token *parens_expression(struct token *token, struct expression **expr, const char *where);
294f08c3bdfSopenharmony_cistruct token *string_expression(struct token *token, struct expression **expr, const char *where);
295f08c3bdfSopenharmony_cistruct token *assignment_expression(struct token *token, struct expression **tree);
296f08c3bdfSopenharmony_ci
297f08c3bdfSopenharmony_ciextern int expand_symbol(struct symbol *);
298f08c3bdfSopenharmony_ci
299f08c3bdfSopenharmony_cistatic inline struct expression *alloc_expression(struct position pos, int type)
300f08c3bdfSopenharmony_ci{
301f08c3bdfSopenharmony_ci	struct expression *expr = __alloc_expression(0);
302f08c3bdfSopenharmony_ci	expr->type = type;
303f08c3bdfSopenharmony_ci	expr->pos = pos;
304f08c3bdfSopenharmony_ci	expr->flags = CEF_NONE;
305f08c3bdfSopenharmony_ci	return expr;
306f08c3bdfSopenharmony_ci}
307f08c3bdfSopenharmony_ci
308f08c3bdfSopenharmony_cistatic inline struct expression *alloc_const_expression(struct position pos, int value)
309f08c3bdfSopenharmony_ci{
310f08c3bdfSopenharmony_ci	struct expression *expr = __alloc_expression(0);
311f08c3bdfSopenharmony_ci	expr->type = EXPR_VALUE;
312f08c3bdfSopenharmony_ci	expr->pos = pos;
313f08c3bdfSopenharmony_ci	expr->value = value;
314f08c3bdfSopenharmony_ci	expr->ctype = &int_ctype;
315f08c3bdfSopenharmony_ci	expr->flags = CEF_SET_INT;
316f08c3bdfSopenharmony_ci	return expr;
317f08c3bdfSopenharmony_ci}
318f08c3bdfSopenharmony_ci
319f08c3bdfSopenharmony_ci/* Type name parsing */
320f08c3bdfSopenharmony_cistruct token *typename(struct token *, struct symbol **, int *);
321f08c3bdfSopenharmony_ci
322f08c3bdfSopenharmony_cistatic inline int lookup_type(struct token *token)
323f08c3bdfSopenharmony_ci{
324f08c3bdfSopenharmony_ci	if (token->pos.type == TOKEN_IDENT) {
325f08c3bdfSopenharmony_ci		struct symbol *sym = lookup_symbol(token->ident, NS_SYMBOL | NS_TYPEDEF);
326f08c3bdfSopenharmony_ci		return sym && (sym->namespace & NS_TYPEDEF);
327f08c3bdfSopenharmony_ci	}
328f08c3bdfSopenharmony_ci	return 0;
329f08c3bdfSopenharmony_ci}
330f08c3bdfSopenharmony_ci
331f08c3bdfSopenharmony_ci/* Statement parsing */
332f08c3bdfSopenharmony_cistruct statement *alloc_statement(struct position pos, int type);
333f08c3bdfSopenharmony_cistruct token *initializer(struct expression **tree, struct token *token);
334f08c3bdfSopenharmony_cistruct token *compound_statement(struct token *, struct statement *);
335f08c3bdfSopenharmony_ci
336f08c3bdfSopenharmony_ci/* The preprocessor calls this 'constant_expression()' */
337f08c3bdfSopenharmony_ci#define constant_expression(token,tree) conditional_expression(token, tree)
338f08c3bdfSopenharmony_ci
339f08c3bdfSopenharmony_ci/* Cast folding of constant values.. */
340f08c3bdfSopenharmony_civoid cast_value(struct expression *expr, struct symbol *newtype,
341f08c3bdfSopenharmony_ci	struct expression *old, struct symbol *oldtype);
342f08c3bdfSopenharmony_ci
343f08c3bdfSopenharmony_ci#endif
344