2 * This file is part of cparser.
3 * Copyright (C) 2007-2009 Matthias Braun <matze@braunis.de>
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * as published by the Free Software Foundation; either version 2
8 * of the License, or (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
28 #include "lang_features.h"
30 static entity_t *create_builtin_function(builtin_kind_t kind, const char *name,
31 type_t *function_type)
33 symbol_t *const symbol = symbol_table_insert(name);
34 entity_t *const entity = allocate_entity_zero(ENTITY_FUNCTION, NAMESPACE_NORMAL, symbol);
35 entity->declaration.storage_class = STORAGE_CLASS_EXTERN;
36 entity->declaration.declared_storage_class = STORAGE_CLASS_EXTERN;
37 entity->declaration.type = function_type;
38 entity->declaration.implicit = true;
39 entity->base.source_position = builtin_source_position;
41 entity->function.btk = kind;
43 record_entity(entity, /*is_definition=*/false);
47 void create_gnu_builtins(void)
49 #define GNU_BUILTIN(a, b) create_builtin_function(bk_gnu_builtin_##a, "__builtin_" #a, b)
51 GNU_BUILTIN(alloca, make_function_1_type(type_void_ptr, type_size_t));
52 GNU_BUILTIN(huge_val, make_function_0_type(type_double));
53 GNU_BUILTIN(huge_valf, make_function_0_type(type_float));
54 GNU_BUILTIN(huge_vall, make_function_0_type(type_long_double));
55 GNU_BUILTIN(inf, make_function_0_type(type_double));
56 GNU_BUILTIN(inff, make_function_0_type(type_float));
57 GNU_BUILTIN(infl, make_function_0_type(type_long_double));
58 GNU_BUILTIN(nan, make_function_1_type(type_double, type_char_ptr));
59 GNU_BUILTIN(nanf, make_function_1_type(type_float, type_char_ptr));
60 GNU_BUILTIN(nanl, make_function_1_type(type_long_double, type_char_ptr));
61 GNU_BUILTIN(va_end, make_function_1_type(type_void, type_valist));
62 GNU_BUILTIN(expect, make_function_2_type(type_long, type_long, type_long));
63 GNU_BUILTIN(return_address, make_function_1_type(type_void_ptr, type_unsigned_int));
64 GNU_BUILTIN(frame_address, make_function_1_type(type_void_ptr, type_unsigned_int));
65 GNU_BUILTIN(ffs, make_function_1_type(type_int, type_unsigned_int));
66 GNU_BUILTIN(clz, make_function_1_type(type_int, type_unsigned_int));
67 GNU_BUILTIN(ctz, make_function_1_type(type_int, type_unsigned_int));
68 GNU_BUILTIN(popcount, make_function_1_type(type_int, type_unsigned_int));
69 GNU_BUILTIN(parity, make_function_1_type(type_int, type_unsigned_int));
70 GNU_BUILTIN(prefetch, make_function_1_type_variadic(type_float, type_void_ptr));
71 GNU_BUILTIN(trap, make_function_type(type_void, 0, NULL, DM_NORETURN));
72 GNU_BUILTIN(object_size, make_function_2_type(type_size_t, type_void_ptr, type_int));
73 GNU_BUILTIN(abort, make_function_type(type_void, 0, NULL, DM_NORETURN));
74 GNU_BUILTIN(abs, make_function_type(type_int, 1, (type_t *[]) { type_int }, DM_CONST));
75 GNU_BUILTIN(labs, make_function_type(type_long, 1, (type_t *[]) { type_long }, DM_CONST));
76 GNU_BUILTIN(llabs, make_function_type(type_long_long, 1, (type_t *[]) { type_long_long }, DM_CONST));
77 GNU_BUILTIN(memcpy, make_function_type(type_void_ptr, 3, (type_t *[]) { type_void_ptr_restrict, type_const_void_ptr_restrict, type_size_t }, DM_NONE));
78 GNU_BUILTIN(__memcpy_chk, make_function_type(type_void_ptr, 4, (type_t *[]) { type_void_ptr_restrict, type_const_void_ptr_restrict, type_size_t, type_size_t}, DM_NONE));
79 GNU_BUILTIN(memcmp, make_function_type(type_int, 3, (type_t *[]) { type_const_void_ptr, type_const_void_ptr, type_size_t }, DM_PURE));
80 GNU_BUILTIN(memset, make_function_type(type_void_ptr, 3, (type_t *[]) { type_void_ptr, type_int, type_size_t }, DM_NONE));
81 GNU_BUILTIN(__memset_chk, make_function_type(type_void_ptr, 4, (type_t *[]) { type_void_ptr, type_int, type_size_t, type_size_t }, DM_NONE));
82 GNU_BUILTIN(memmove, make_function_type(type_void_ptr, 3, (type_t *[]) { type_void_ptr_restrict, type_const_void_ptr_restrict, type_size_t }, DM_NONE));
83 GNU_BUILTIN(__memmove_chk, make_function_type(type_void_ptr, 4, (type_t *[]) { type_void_ptr_restrict, type_const_void_ptr_restrict, type_size_t, type_size_t }, DM_NONE));
84 GNU_BUILTIN(strcat, make_function_type(type_char_ptr, 2, (type_t *[]) { type_char_ptr_restrict, type_const_char_ptr_restrict }, DM_NONE));
85 GNU_BUILTIN(__strcat_chk, make_function_type(type_char_ptr, 3, (type_t *[]) { type_char_ptr_restrict, type_const_char_ptr_restrict, type_size_t }, DM_NONE));
86 GNU_BUILTIN(strncat, make_function_type(type_char_ptr, 3, (type_t *[]) { type_char_ptr_restrict, type_const_char_ptr_restrict, type_size_t }, DM_NONE));
87 GNU_BUILTIN(__strncat_chk, make_function_type(type_char_ptr, 4, (type_t *[]) { type_char_ptr_restrict, type_const_char_ptr_restrict, type_size_t, type_size_t }, DM_NONE));
88 GNU_BUILTIN(strlen, make_function_type(type_size_t, 1, (type_t *[]) { type_const_char_ptr }, DM_PURE));
89 GNU_BUILTIN(strcmp, make_function_type(type_int, 2, (type_t *[]) { type_const_char_ptr, type_const_char_ptr }, DM_PURE));
90 GNU_BUILTIN(strcpy, make_function_type(type_char_ptr, 2, (type_t *[]) { type_char_ptr_restrict, type_const_char_ptr_restrict }, DM_NONE));
91 GNU_BUILTIN(__strcpy_chk, make_function_type(type_char_ptr, 3, (type_t *[]) { type_char_ptr_restrict, type_const_char_ptr_restrict, type_size_t }, DM_NONE));
92 GNU_BUILTIN(stpcpy, make_function_type(type_char_ptr, 2, (type_t *[]) { type_char_ptr_restrict, type_const_char_ptr_restrict }, DM_NONE));
93 GNU_BUILTIN(__stpcpy_chk, make_function_type(type_char_ptr, 3, (type_t *[]) { type_char_ptr_restrict, type_const_char_ptr_restrict, type_size_t }, DM_NONE));
94 GNU_BUILTIN(strncpy, make_function_type(type_char_ptr, 3, (type_t *[]) { type_char_ptr_restrict, type_const_char_ptr_restrict, type_size_t }, DM_NONE));
95 GNU_BUILTIN(__strncpy_chk, make_function_type(type_char_ptr, 4, (type_t *[]) { type_char_ptr_restrict, type_const_char_ptr_restrict, type_size_t, type_size_t }, DM_NONE));
96 GNU_BUILTIN(exit, make_function_type(type_void, 1, (type_t *[]) { type_int }, DM_NORETURN));
97 GNU_BUILTIN(malloc, make_function_type(type_void_ptr, 1, (type_t *[]) { type_size_t }, DM_MALLOC));
99 /* TODO: gcc has a LONG list of builtin functions (nearly everything from
100 * C89-C99 and others. Complete this */
105 static const char *get_builtin_replacement_name(builtin_kind_t kind)
108 case bk_gnu_builtin___memcpy_chk: return "memcpy";
109 case bk_gnu_builtin___memmove_chk: return "memmove";
110 case bk_gnu_builtin___memset_chk: return "memset";
111 case bk_gnu_builtin___snprintf_chk: return "snprintf";
112 case bk_gnu_builtin___sprintf_chk: return "sprintf";
113 case bk_gnu_builtin___stpcpy_chk: return "stpcpy";
114 case bk_gnu_builtin___strcat_chk: return "strcat";
115 case bk_gnu_builtin___strcpy_chk: return "strcpy";
116 case bk_gnu_builtin___strncat_chk: return "strncat";
117 case bk_gnu_builtin___strncpy_chk: return "strncpy";
118 case bk_gnu_builtin___vsnprintf_chk: return "vsnprintf";
119 case bk_gnu_builtin___vsprintf_chk: return "vsprintf";
120 case bk_gnu_builtin_abort: return "abort";
121 case bk_gnu_builtin_abs: return "abs";
122 case bk_gnu_builtin_exit: return "exit";
123 case bk_gnu_builtin_labs: return "labs";
124 case bk_gnu_builtin_llabs: return "llabs";
125 case bk_gnu_builtin_malloc: return "malloc";
126 case bk_gnu_builtin_memcmp: return "memcmp";
127 case bk_gnu_builtin_memcpy: return "memcpy";
128 case bk_gnu_builtin_memmove: return "memmove";
129 case bk_gnu_builtin_memset: return "memset";
130 case bk_gnu_builtin_snprintf: return "snprintf";
131 case bk_gnu_builtin_sprintf: return "sprintf";
132 case bk_gnu_builtin_stpcpy: return "stpcpy";
133 case bk_gnu_builtin_strcat: return "strcat";
134 case bk_gnu_builtin_strcmp: return "strcmp";
135 case bk_gnu_builtin_strcpy: return "strcpy";
136 case bk_gnu_builtin_strlen: return "strlen";
137 case bk_gnu_builtin_strncat: return "strncat";
138 case bk_gnu_builtin_strncpy: return "strncpy";
139 case bk_gnu_builtin_vsnprintf: return "vsnprintf";
140 case bk_gnu_builtin_vsprintf: return "vsprintf";
148 int get_builtin_chk_arg_pos(builtin_kind_t kind)
151 case bk_gnu_builtin___sprintf_chk:
152 case bk_gnu_builtin___strcat_chk:
153 case bk_gnu_builtin___strcpy_chk:
154 case bk_gnu_builtin___vsprintf_chk:
156 case bk_gnu_builtin___memcpy_chk:
157 case bk_gnu_builtin___memmove_chk:
158 case bk_gnu_builtin___memset_chk:
159 case bk_gnu_builtin___snprintf_chk:
160 case bk_gnu_builtin___strncat_chk:
161 case bk_gnu_builtin___strncpy_chk:
162 case bk_gnu_builtin___vsnprintf_chk:
170 entity_t *get_builtin_replacement(const entity_t *builtin_entity)
172 builtin_kind_t kind = builtin_entity->function.btk;
173 const char *replacement = get_builtin_replacement_name(kind);
174 if (replacement == NULL)
177 symbol_t *const symbol = symbol_table_insert(replacement);
178 entity_t *const entity = allocate_entity_zero(ENTITY_FUNCTION, NAMESPACE_NORMAL, symbol);
179 entity->base.source_position = builtin_source_position;
180 entity->declaration.storage_class = STORAGE_CLASS_EXTERN;
181 entity->declaration.declared_storage_class = STORAGE_CLASS_EXTERN;
182 entity->declaration.type = builtin_entity->declaration.type;
183 entity->declaration.implicit = true;
184 entity->declaration.modifiers = builtin_entity->declaration.modifiers;
189 void create_microsoft_intrinsics(void)
191 #define MS_BUILTIN(a, b) create_builtin_function(bk_ms##a, #a, b)
193 /* intrinsics for all architectures */
194 MS_BUILTIN(_rotl, make_function_2_type(type_unsigned_int, type_unsigned_int, type_int));
195 MS_BUILTIN(_rotr, make_function_2_type(type_unsigned_int, type_unsigned_int, type_int));
196 MS_BUILTIN(_rotl64, make_function_2_type(type_unsigned_int64, type_unsigned_int64, type_int));
197 MS_BUILTIN(_rotr64, make_function_2_type(type_unsigned_int64, type_unsigned_int64, type_int));
198 MS_BUILTIN(_byteswap_ushort, make_function_1_type(type_unsigned_short, type_unsigned_short));
199 MS_BUILTIN(_byteswap_ulong, make_function_1_type(type_unsigned_long, type_unsigned_long));
200 MS_BUILTIN(_byteswap_uint64, make_function_1_type(type_unsigned_int64, type_unsigned_int64));
202 MS_BUILTIN(__debugbreak, make_function_0_type(type_void));
203 MS_BUILTIN(_ReturnAddress, make_function_0_type(type_void_ptr));
204 MS_BUILTIN(_AddressOfReturnAddress, make_function_0_type(type_void_ptr));
205 MS_BUILTIN(__popcount, make_function_1_type(type_unsigned_int, type_unsigned_int));
208 MS_BUILTIN(_enable, make_function_0_type(type_void));
209 MS_BUILTIN(_disable, make_function_0_type(type_void));
210 MS_BUILTIN(__inbyte, make_function_1_type(type_unsigned_char, type_unsigned_short));
211 MS_BUILTIN(__inword, make_function_1_type(type_unsigned_short, type_unsigned_short));
212 MS_BUILTIN(__indword, make_function_1_type(type_unsigned_long, type_unsigned_short));
213 MS_BUILTIN(__outbyte, make_function_2_type(type_void, type_unsigned_short, type_unsigned_char));
214 MS_BUILTIN(__outword, make_function_2_type(type_void, type_unsigned_short, type_unsigned_short));
215 MS_BUILTIN(__outdword, make_function_2_type(type_void, type_unsigned_short, type_unsigned_long));
216 MS_BUILTIN(__ud2, make_function_type(type_void, 0, NULL, DM_NORETURN));
217 MS_BUILTIN(_BitScanForward, make_function_2_type(type_unsigned_char, type_unsigned_long_ptr, type_unsigned_long));
218 MS_BUILTIN(_BitScanReverse, make_function_2_type(type_unsigned_char, type_unsigned_long_ptr, type_unsigned_long));
219 MS_BUILTIN(_InterlockedExchange, make_function_2_type(type_long, type_long_ptr, type_long));
220 MS_BUILTIN(_InterlockedExchange64, make_function_2_type(type_int64, type_int64_ptr, type_int64));