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(ffsl, make_function_1_type(type_int, type_unsigned_long));
67 GNU_BUILTIN(ffsll, make_function_1_type(type_int, type_unsigned_long_long));
68 GNU_BUILTIN(clz, make_function_1_type(type_int, type_unsigned_int));
69 GNU_BUILTIN(clzl, make_function_1_type(type_int, type_unsigned_long));
70 GNU_BUILTIN(clzll, make_function_1_type(type_int, type_unsigned_long_long));
71 GNU_BUILTIN(ctz, make_function_1_type(type_int, type_unsigned_int));
72 GNU_BUILTIN(ctzl, make_function_1_type(type_int, type_unsigned_long));
73 GNU_BUILTIN(ctzll, make_function_1_type(type_int, type_unsigned_long_long));
74 GNU_BUILTIN(popcount, make_function_1_type(type_int, type_unsigned_int));
75 GNU_BUILTIN(popcountl, make_function_1_type(type_int, type_unsigned_long));
76 GNU_BUILTIN(popcountll, make_function_1_type(type_int, type_unsigned_long_long));
77 GNU_BUILTIN(parity, make_function_1_type(type_int, type_unsigned_int));
78 GNU_BUILTIN(prefetch, make_function_1_type_variadic(type_float, type_void_ptr));
79 GNU_BUILTIN(trap, make_function_type(type_void, 0, NULL, DM_NORETURN));
80 GNU_BUILTIN(object_size, make_function_2_type(type_size_t, type_void_ptr, type_int));
81 GNU_BUILTIN(abort, make_function_type(type_void, 0, NULL, DM_NORETURN));
82 GNU_BUILTIN(abs, make_function_type(type_int, 1, (type_t *[]) { type_int }, DM_CONST));
83 GNU_BUILTIN(labs, make_function_type(type_long, 1, (type_t *[]) { type_long }, DM_CONST));
84 GNU_BUILTIN(llabs, make_function_type(type_long_long, 1, (type_t *[]) { type_long_long }, DM_CONST));
85 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));
86 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));
87 GNU_BUILTIN(memcmp, make_function_type(type_int, 3, (type_t *[]) { type_const_void_ptr, type_const_void_ptr, type_size_t }, DM_PURE));
88 GNU_BUILTIN(memset, make_function_type(type_void_ptr, 3, (type_t *[]) { type_void_ptr, type_int, type_size_t }, DM_NONE));
89 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));
90 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));
91 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));
92 GNU_BUILTIN(strcat, make_function_type(type_char_ptr, 2, (type_t *[]) { type_char_ptr_restrict, type_const_char_ptr_restrict }, DM_NONE));
93 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));
94 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));
95 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));
96 GNU_BUILTIN(strlen, make_function_type(type_size_t, 1, (type_t *[]) { type_const_char_ptr }, DM_PURE));
97 GNU_BUILTIN(strcmp, make_function_type(type_int, 2, (type_t *[]) { type_const_char_ptr, type_const_char_ptr }, DM_PURE));
98 GNU_BUILTIN(strcpy, make_function_type(type_char_ptr, 2, (type_t *[]) { type_char_ptr_restrict, type_const_char_ptr_restrict }, DM_NONE));
99 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));
100 GNU_BUILTIN(stpcpy, make_function_type(type_char_ptr, 2, (type_t *[]) { type_char_ptr_restrict, type_const_char_ptr_restrict }, DM_NONE));
101 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));
102 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));
103 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));
104 GNU_BUILTIN(exit, make_function_type(type_void, 1, (type_t *[]) { type_int }, DM_NORETURN));
105 GNU_BUILTIN(malloc, make_function_type(type_void_ptr, 1, (type_t *[]) { type_size_t }, DM_MALLOC));
107 /* TODO: gcc has a LONG list of builtin functions (nearly everything from
108 * C89-C99 and others. Complete this */
113 static const char *get_builtin_replacement_name(builtin_kind_t kind)
116 case bk_gnu_builtin___memcpy_chk: return "memcpy";
117 case bk_gnu_builtin___memmove_chk: return "memmove";
118 case bk_gnu_builtin___memset_chk: return "memset";
119 case bk_gnu_builtin___snprintf_chk: return "snprintf";
120 case bk_gnu_builtin___sprintf_chk: return "sprintf";
121 case bk_gnu_builtin___stpcpy_chk: return "stpcpy";
122 case bk_gnu_builtin___strcat_chk: return "strcat";
123 case bk_gnu_builtin___strcpy_chk: return "strcpy";
124 case bk_gnu_builtin___strncat_chk: return "strncat";
125 case bk_gnu_builtin___strncpy_chk: return "strncpy";
126 case bk_gnu_builtin___vsnprintf_chk: return "vsnprintf";
127 case bk_gnu_builtin___vsprintf_chk: return "vsprintf";
128 case bk_gnu_builtin_abort: return "abort";
129 case bk_gnu_builtin_abs: return "abs";
130 case bk_gnu_builtin_exit: return "exit";
131 case bk_gnu_builtin_labs: return "labs";
132 case bk_gnu_builtin_llabs: return "llabs";
133 case bk_gnu_builtin_malloc: return "malloc";
134 case bk_gnu_builtin_memcmp: return "memcmp";
135 case bk_gnu_builtin_memcpy: return "memcpy";
136 case bk_gnu_builtin_memmove: return "memmove";
137 case bk_gnu_builtin_memset: return "memset";
138 case bk_gnu_builtin_snprintf: return "snprintf";
139 case bk_gnu_builtin_sprintf: return "sprintf";
140 case bk_gnu_builtin_stpcpy: return "stpcpy";
141 case bk_gnu_builtin_strcat: return "strcat";
142 case bk_gnu_builtin_strcmp: return "strcmp";
143 case bk_gnu_builtin_strcpy: return "strcpy";
144 case bk_gnu_builtin_strlen: return "strlen";
145 case bk_gnu_builtin_strncat: return "strncat";
146 case bk_gnu_builtin_strncpy: return "strncpy";
147 case bk_gnu_builtin_vsnprintf: return "vsnprintf";
148 case bk_gnu_builtin_vsprintf: return "vsprintf";
156 int get_builtin_chk_arg_pos(builtin_kind_t kind)
159 case bk_gnu_builtin___sprintf_chk:
160 case bk_gnu_builtin___strcat_chk:
161 case bk_gnu_builtin___strcpy_chk:
162 case bk_gnu_builtin___vsprintf_chk:
164 case bk_gnu_builtin___memcpy_chk:
165 case bk_gnu_builtin___memmove_chk:
166 case bk_gnu_builtin___memset_chk:
167 case bk_gnu_builtin___snprintf_chk:
168 case bk_gnu_builtin___strncat_chk:
169 case bk_gnu_builtin___strncpy_chk:
170 case bk_gnu_builtin___vsnprintf_chk:
178 entity_t *get_builtin_replacement(const entity_t *builtin_entity)
180 builtin_kind_t kind = builtin_entity->function.btk;
181 const char *replacement = get_builtin_replacement_name(kind);
182 if (replacement == NULL)
185 symbol_t *const symbol = symbol_table_insert(replacement);
186 entity_t *const entity = allocate_entity_zero(ENTITY_FUNCTION, NAMESPACE_NORMAL, symbol);
187 entity->base.source_position = builtin_source_position;
188 entity->declaration.storage_class = STORAGE_CLASS_EXTERN;
189 entity->declaration.declared_storage_class = STORAGE_CLASS_EXTERN;
190 entity->declaration.type = builtin_entity->declaration.type;
191 entity->declaration.implicit = true;
192 entity->declaration.modifiers = builtin_entity->declaration.modifiers;
197 void create_microsoft_intrinsics(void)
199 #define MS_BUILTIN(a, b) create_builtin_function(bk_ms##a, #a, b)
201 /* intrinsics for all architectures */
202 MS_BUILTIN(_rotl, make_function_2_type(type_unsigned_int, type_unsigned_int, type_int));
203 MS_BUILTIN(_rotr, make_function_2_type(type_unsigned_int, type_unsigned_int, type_int));
204 MS_BUILTIN(_rotl64, make_function_2_type(type_unsigned_int64, type_unsigned_int64, type_int));
205 MS_BUILTIN(_rotr64, make_function_2_type(type_unsigned_int64, type_unsigned_int64, type_int));
206 MS_BUILTIN(_byteswap_ushort, make_function_1_type(type_unsigned_short, type_unsigned_short));
207 MS_BUILTIN(_byteswap_ulong, make_function_1_type(type_unsigned_long, type_unsigned_long));
208 MS_BUILTIN(_byteswap_uint64, make_function_1_type(type_unsigned_int64, type_unsigned_int64));
210 MS_BUILTIN(__debugbreak, make_function_0_type(type_void));
211 MS_BUILTIN(_ReturnAddress, make_function_0_type(type_void_ptr));
212 MS_BUILTIN(_AddressOfReturnAddress, make_function_0_type(type_void_ptr));
213 MS_BUILTIN(__popcount, make_function_1_type(type_unsigned_int, type_unsigned_int));
216 MS_BUILTIN(_enable, make_function_0_type(type_void));
217 MS_BUILTIN(_disable, make_function_0_type(type_void));
218 MS_BUILTIN(__inbyte, make_function_1_type(type_unsigned_char, type_unsigned_short));
219 MS_BUILTIN(__inword, make_function_1_type(type_unsigned_short, type_unsigned_short));
220 MS_BUILTIN(__indword, make_function_1_type(type_unsigned_long, type_unsigned_short));
221 MS_BUILTIN(__outbyte, make_function_2_type(type_void, type_unsigned_short, type_unsigned_char));
222 MS_BUILTIN(__outword, make_function_2_type(type_void, type_unsigned_short, type_unsigned_short));
223 MS_BUILTIN(__outdword, make_function_2_type(type_void, type_unsigned_short, type_unsigned_long));
224 MS_BUILTIN(__ud2, make_function_type(type_void, 0, NULL, DM_NORETURN));
225 MS_BUILTIN(_BitScanForward, make_function_2_type(type_unsigned_char, type_unsigned_long_ptr, type_unsigned_long));
226 MS_BUILTIN(_BitScanReverse, make_function_2_type(type_unsigned_char, type_unsigned_long_ptr, type_unsigned_long));
227 MS_BUILTIN(_InterlockedExchange, make_function_2_type(type_long, type_long_ptr, type_long));
228 MS_BUILTIN(_InterlockedExchange64, make_function_2_type(type_int64, type_int64_ptr, type_int64));