1/*
2 * Copyright (c) 2010 Apple Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * 1.  Redistributions of source code must retain the above copyright
11 *     notice, this list of conditions and the following disclaimer.
12 * 2.  Redistributions in binary form must reproduce the above copyright
13 *     notice, this list of conditions and the following disclaimer in the
14 *     documentation and/or other materials provided with the distribution.
15 * 3.  Neither the name of Apple Inc. ("Apple") nor the names of its
16 *     contributors may be used to endorse or promote products derived from
17 *     this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
20 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
23 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
26 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 *
30 * Portions of this software have been released under the following terms:
31 *
32 * (c) Copyright 1989-1993 OPEN SOFTWARE FOUNDATION, INC.
33 * (c) Copyright 1989-1993 HEWLETT-PACKARD COMPANY
34 * (c) Copyright 1989-1993 DIGITAL EQUIPMENT CORPORATION
35 *
36 * To anyone who acknowledges that this file is provided "AS IS"
37 * without any express or implied warranty:
38 * permission to use, copy, modify, and distribute this file for any
39 * purpose is hereby granted without fee, provided that the above
40 * copyright notices and this notice appears in all source code copies,
41 * and that none of the names of Open Software Foundation, Inc., Hewlett-
42 * Packard Company or Digital Equipment Corporation be used
43 * in advertising or publicity pertaining to distribution of the software
44 * without specific, written prior permission.  Neither Open Software
45 * Foundation, Inc., Hewlett-Packard Company nor Digital
46 * Equipment Corporation makes any representations about the suitability
47 * of this software for any purpose.
48 *
49 * Copyright (c) 2007, Novell, Inc. All rights reserved.
50 * Redistribution and use in source and binary forms, with or without
51 * modification, are permitted provided that the following conditions
52 * are met:
53 *
54 * 1.  Redistributions of source code must retain the above copyright
55 *     notice, this list of conditions and the following disclaimer.
56 * 2.  Redistributions in binary form must reproduce the above copyright
57 *     notice, this list of conditions and the following disclaimer in the
58 *     documentation and/or other materials provided with the distribution.
59 * 3.  Neither the name of Novell Inc. nor the names of its contributors
60 *     may be used to endorse or promote products derived from this
61 *     this software without specific prior written permission.
62 *
63 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
64 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
65 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
66 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY
67 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
68 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
69 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
70 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
71 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
72 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
73 *
74 * @APPLE_LICENSE_HEADER_END@
75 */
76
77/*
78**
79**  NAME:
80**
81**      checker.h
82**
83**  FACILITY:
84**
85**      Interface Definition Language (IDL) Compiler
86**
87**  ABSTRACT:
88**
89**  Declaration of functions exported by checker.c.
90**
91**  VERSION: DCE 1.0
92**
93*/
94
95#ifndef CHECKERH_INCL
96#define CHECKERH_INCL
97
98#include <ast.h>                /* Abstract Syntax Tree defs */
99
100/*
101**  m i s c   m a c r o s
102**
103**  Miscellaneous macros.
104*/
105
106/* Evaluates to the text for the 'standard extended' command option */
107#define OPT_STD_EXTENDED "-standard extended"
108
109/*
110 * Get the last field in a structure.  The first field in a structure has a
111 * pointer to the last field, unless it is the only field in the structure.
112 */
113#define struct_last_field(struct_p) \
114    (((struct_p)->fields->last == NULL) ? \
115        (struct_p)->fields : (struct_p)->fields->last)
116
117/*
118**  p r o p e r t y   m a c r o s
119**
120**  Property macros - determine whether a data structure has some property.
121*/
122
123#define uuid_is_null(uuid_p) \
124    ((uuid_p)->time_low                     == 0 \
125    &&  (uuid_p)->time_mid                  == 0 \
126    &&  (uuid_p)->time_hi_and_version       == 0 \
127    &&  (uuid_p)->clock_seq_hi_and_reserved == 0 \
128    &&  (uuid_p)->clock_seq_low             == 0 \
129    &&  (uuid_p)->node[0]                   == 0 \
130    &&  (uuid_p)->node[1]                   == 0 \
131    &&  (uuid_p)->node[2]                   == 0 \
132    &&  (uuid_p)->node[3]                   == 0 \
133    &&  (uuid_p)->node[4]                   == 0 \
134    &&  (uuid_p)->node[5]                   == 0)
135
136/*
137**  t y p e   m a c r o s
138**
139**  Type "properties" used by other checks.
140*/
141
142#define type_is_handle(type_p) \
143    ((type_p)->kind == AST_handle_k \
144    ||  AST_HANDLE_SET(type_p))
145
146#define param_is_handle(param_p) \
147    ( ((param_p)->type->kind == AST_handle_k \
148       || AST_HANDLE_SET((param_p)->type)) \
149     || (AST_REF_SET(param_p) \
150         && (param_p)->type->kind == AST_pointer_k \
151         && ( (param_p)->type->type_structure.pointer->pointee_type->kind \
152                  == AST_handle_k \
153              || AST_HANDLE_SET( \
154                  (param_p)->type->type_structure.pointer->pointee_type) ) ) )
155
156#define type_is_integer(type_p) \
157    ((type_p)->kind == AST_small_integer_k \
158    ||  (type_p)->kind == AST_short_integer_k \
159    ||  (type_p)->kind == AST_long_integer_k \
160    ||  (type_p)->kind == AST_hyper_integer_k \
161    ||  (type_p)->kind == AST_small_unsigned_k \
162    ||  (type_p)->kind == AST_short_unsigned_k \
163    ||  (type_p)->kind == AST_long_unsigned_k \
164    ||  (type_p)->kind == AST_hyper_unsigned_k)
165
166#define type_is_multibyte_integer(type_p) \
167    ((type_p)->kind == AST_short_integer_k \
168    ||  (type_p)->kind == AST_long_integer_k \
169    ||  (type_p)->kind == AST_hyper_integer_k \
170    ||  (type_p)->kind == AST_short_unsigned_k \
171    ||  (type_p)->kind == AST_long_unsigned_k \
172    ||  (type_p)->kind == AST_hyper_unsigned_k)
173
174#define type_is_enum(type_p) \
175    ((type_p)->kind == AST_enum_k)
176
177#define type_is_float(type_p) \
178    ((type_p)->kind == AST_short_float_k \
179    ||  (type_p)->kind == AST_long_float_k)
180
181#define type_is_scalar(type_p) \
182    ((type_p)->kind == AST_boolean_k \
183    ||  (type_p)->kind == AST_byte_k \
184    ||  (type_p)->kind == AST_character_k \
185    ||  type_is_integer(type_p) \
186    ||  type_is_enum(type_p) \
187    ||  type_is_float(type_p))
188
189#define type_is_index(type_p) \
190    (type_is_integer(type_p) \
191      && ((type_p)->kind != AST_hyper_unsigned_k) \
192      && ((type_p)->kind != AST_hyper_integer_k))
193
194#define type_is_rangeable(type_p) \
195    (type_is_scalar(type_p) \
196      && !type_is_enum(type_p) \
197      && ((type_p)->kind != AST_hyper_unsigned_k) \
198      && ((type_p)->kind != AST_hyper_integer_k))
199
200/*
201 *  Notes on arrays: An array can be represented in array or pointer syntax.
202 *  Array syntax is straightforward.  In general, whether a pointer type
203 *  represents an array is not known at the type definition, only at the
204 *  type instance.  The one exception to this is the [string] attribute,
205 *  which "arrayifies" a pointer type ([v1_array] and [v1_string] are only
206 *  allowed in the array syntax form, so they can't arrayify a pointer).
207 *  An instance of a pointer type represents an array if it has any of the
208 *  array size attributes, or if it has the [string] attribute.
209 */
210#define type_is_array(type_p) \
211    ((type_p)->kind == AST_array_k \
212    ||  ((type_p)->kind == AST_pointer_k && AST_STRING_SET(type_p)))
213
214#define type_is_array_np(type_p) \
215    ((type_p)->kind == AST_array_k)
216
217#define type_is_array_1dim(type_p) \
218    (   ((type_p)->kind == AST_array_k \
219        &&  (type_p)->type_structure.array->index_count == 1) \
220    ||  ((type_p)->kind == AST_pointer_k && AST_STRING_SET(type_p)))
221
222#define type_is_anonymous(type_p) \
223    ((type_p)->name == NAMETABLE_NIL_ID \
224    &&  !type_is_base(type_p))
225
226#define type_is_function(type_p) \
227    ((type_p)->kind == AST_pointer_k \
228    &&  (type_p)->type_structure.pointer->pointee_type->kind \
229        == AST_function_k)
230
231/*
232**  i n s t a n c e   m a c r o s
233**
234**  Instance-of-type "properties" used by other checks.
235*/
236
237#if 0
238#define instance_is_array(type_p, fattr_p, flags) \
239    ((type_p)->kind == AST_array_k \
240    ||  ((type_p)->kind == AST_pointer_k \
241        &&  (AST_STRING_SET(type_p) \
242            ||  fattr_p != NULL \
243            ||  (AST_STRING & flags))))
244#endif
245
246#define instance_is_array(type_p, fattr_p, flags) \
247    ((type_p)->kind == AST_array_k \
248    ||  ((type_p)->kind == AST_pointer_k \
249        &&  (AST_STRING_SET(type_p) \
250            || (fattr_p != NULL && \
251                 (fattr_p->max_is_vec != NULL || fattr_p->size_is_vec != NULL))\
252            || (AST_STRING & flags))))
253
254#define instance_has_array_attr(inst_p) \
255    ((inst_p)->field_attrs != NULL \
256     && ((inst_p)->field_attrs->min_is_vec != NULL \
257         || (inst_p)->field_attrs->max_is_vec != NULL \
258         || (inst_p)->field_attrs->size_is_vec != NULL \
259         || (inst_p)->field_attrs->first_is_vec != NULL \
260         || (inst_p)->field_attrs->last_is_vec != NULL \
261         || (inst_p)->field_attrs->length_is_vec != NULL))
262
263/*
264**  c o n s t a n t   m a c r o s
265**
266**  Constant "properties" used by other checks.
267*/
268
269#define const_is_integer(const_p) \
270        ((const_p)->kind == AST_int_const_k \
271        &&  (const_p)->fe_info->type_specific.const_kind == fe_int_const_k)
272
273#define const_is_enum(const_p) \
274        ((const_p)->kind == AST_int_const_k \
275        &&  (const_p)->fe_info->type_specific.const_kind == fe_enum_const_k)
276
277/*
278**  C H K _ s t r u c t _ i s _ a l l _ b y t e _ f i e l d s
279**
280**  Returns TRUE if a struct consists only of scalar byte fields.
281*/
282
283extern boolean CHK_struct_is_all_byte_fields(
284    AST_structure_n_t   *struct_p       /* [in] Ptr to AST structure node */
285);
286
287/*
288**  p a r a m _ f o l l o w _ r e f _ p t r
289**
290**  Dereferences a parameter's type if it is a pointer and it meets certain
291**  conditions.  Some of the conditions apply always; others are dependent
292**  on the 'mode' argument (see below).
293**
294**  The general intent of this function is to follow reference pointers.
295**  However, there are ambiguities as to what that really means, and
296**  different dereferencing behavior is required depending on the need.
297**  Thus, the 'mode' argument allows one to tweak what this routine does.
298**
299**  Returns address of pointee type node if the type was dereferenced.
300**  Returns address of parameter's type node if the type was NOT dereferenced.
301*/
302
303/*
304 * Enum which dictates the behavior of param_follow_ref_ptr.
305 *
306 * In NO cases does it follow:
307 *  - a pointer function result parameter, which by def can't be a ref ptr
308 *  - void *, since "void passed-by-reference" makes no sense
309 *  - function pointer
310 *  - arrayified [string] pointers (but not pointer to string array)
311 */
312typedef enum
313{
314    CHK_follow_ref,     /* Follow [ref] but not [unique] or [ptr] pointers   */
315                        /* Do not follow pointers arrayified via size attrs  */
316                        /* Do not follow pointers arrayified via string attr */
317                        /* DO follow named pointers                          */
318CHK_follow_ref_arr_siz, /* Follow [ref] but not [unique] or [ptr] pointers   */
319                        /* DO follow pointers arrayified via size attrs      */
320                        /* Do not follow pointers arrayified via string attr */
321                        /* DO follow named pointers                          */
322    CHK_follow_any      /* Follow [ref], [unique], or [ptr] pointers         */
323                        /* Do not follow pointers arrayified via size attrs  */
324                        /* Do not follow pointers arrayified via string attr */
325                        /* Do not follow named pointers                      */
326} CHK_follow_t;
327
328extern AST_type_n_t * param_follow_ref_ptr( /* Returns ptr to type node */
329    AST_parameter_n_t   *param_p,       /* [in] Ptr to AST parameter node */
330    CHK_follow_t        mode            /* [in] Follow mode (see above) */
331);
332
333/*
334**  t y p e _ i s _ b a s e
335**
336**  Returns true if the specified type node is for a base type, false otherwise.
337*/
338
339extern boolean type_is_base(
340    AST_type_n_t *type_p    /* [in] Ptr to AST type node */
341);
342
343/*
344**  C H E C K E R _ m a i n
345**
346**  Main routine of semantic checking component of IDL compiler.
347**  Does semantic checking of the interface definition (and any imported
348**  items that are referred to in the interface).
349*/
350
351extern boolean CHECKER_main(    /* Returns true on success */
352    boolean     *cmd_opt_arr,   /* [in] Array of command option flags */
353    void        **cmd_val_arr,  /* [in] Array of command option values */
354    AST_interface_n_t *int_p    /* [in] Ptr to AST interface node */
355);
356
357extern void CHECKER_error(
358	void *in_node_p,
359	long msg_id,
360	...
361);
362
363extern void CHECKER_warning(
364 void *in_node_p,
365 long msg_id,
366 ...
367);
368
369extern void CHECKER_acf_error(
370 void *in_node_p,
371 long msg_id,
372 ...
373);
374
375extern void CHECKER_acf_warning(
376 void *in_node_p,
377 long msg_id,
378 ...
379);
380
381#endif
382