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
22 #include "adt/strutil.h"
30 #include "lang_features.h"
32 static entity_t *create_builtin_function(builtin_kind_t kind, symbol_t *symbol,
33 type_t *function_type)
35 entity_t *const entity = allocate_entity_zero(ENTITY_FUNCTION, NAMESPACE_NORMAL, symbol, &builtin_source_position);
36 entity->declaration.storage_class = STORAGE_CLASS_EXTERN;
37 entity->declaration.declared_storage_class = STORAGE_CLASS_EXTERN;
38 entity->declaration.type = function_type;
39 entity->declaration.implicit = true;
40 entity->base.source_position = builtin_source_position;
42 entity->function.btk = kind;
44 record_entity(entity, /*is_definition=*/false);
48 static symbol_t *finalize_symbol_string(void)
50 obstack_1grow(&symbol_obstack, '\0');
51 char *string = obstack_finish(&symbol_obstack);
52 symbol_t *symbol = symbol_table_insert(string);
53 if (symbol->string != string)
54 obstack_free(&symbol_obstack, string);
58 static entity_t *create_gnu_builtin(builtin_kind_t kind, const char *name,
61 obstack_printf(&symbol_obstack, "__builtin_%s", name);
62 symbol_t *symbol = finalize_symbol_string();
63 entity_t *entity = create_builtin_function(kind, symbol, type);
67 static entity_t *create_gnu_builtin_firm(ir_builtin_kind kind, const char *name,
70 obstack_printf(&symbol_obstack, "__builtin_%s", name);
71 symbol_t *symbol = finalize_symbol_string();
72 entity_t *entity = create_builtin_function(BUILTIN_FIRM, symbol, type);
73 entity->function.b.firm_builtin_kind = kind;
77 static entity_t *create_gnu_builtin_libc(const char *name, type_t *type)
79 obstack_printf(&symbol_obstack, "__builtin_%s", name);
80 symbol_t *symbol = finalize_symbol_string();
81 entity_t *entity = create_builtin_function(BUILTIN_LIBC, symbol, type);
82 entity->function.actual_name = symbol_table_insert(name);
86 static entity_t *create_gnu_builtin_chk(const char *name, unsigned chk_arg_pos,
89 obstack_printf(&symbol_obstack, "__builtin___%s_chk", name);
90 symbol_t *symbol = finalize_symbol_string();
91 entity_t *entity = create_builtin_function(BUILTIN_LIBC_CHECK, symbol, type);
92 entity->function.actual_name = symbol_table_insert(name);
93 entity->function.b.chk_arg_pos = chk_arg_pos;
97 void create_gnu_builtins(void)
99 entity_t *(*b)(builtin_kind_t,const char*,type_t*) = create_gnu_builtin;
100 b(BUILTIN_ALLOCA, "alloca", make_function_1_type(type_void_ptr, type_size_t, DM_NONE));
101 b(BUILTIN_INF, "huge_val", make_function_0_type(type_double, DM_CONST));
102 b(BUILTIN_INF, "huge_valf", make_function_0_type(type_float, DM_CONST));
103 b(BUILTIN_INF, "huge_vall", make_function_0_type(type_long_double, DM_CONST));
104 b(BUILTIN_INF, "inf", make_function_0_type(type_double, DM_CONST));
105 b(BUILTIN_INF, "inff", make_function_0_type(type_float, DM_CONST));
106 b(BUILTIN_INF, "infl", make_function_0_type(type_long_double, DM_CONST));
107 b(BUILTIN_NAN, "nan", make_function_1_type(type_double, type_char_ptr, DM_CONST));
108 b(BUILTIN_NAN, "nanf", make_function_1_type(type_float, type_char_ptr, DM_CONST));
109 b(BUILTIN_NAN, "nanl", make_function_1_type(type_long_double, type_char_ptr, DM_CONST));
110 b(BUILTIN_VA_END, "va_end", make_function_1_type(type_void, type_valist, DM_NONE));
111 b(BUILTIN_EXPECT, "expect", make_function_2_type(type_long, type_long, type_long, DM_CONST));
112 b(BUILTIN_OBJECT_SIZE, "object_size", make_function_2_type(type_size_t, type_void_ptr, type_int, DM_CONST));
114 entity_t *(*f)(ir_builtin_kind,const char*,type_t*)
115 = create_gnu_builtin_firm;
116 f(ir_bk_bswap, "bswap32", make_function_1_type(type_int32_t, type_int32_t, DM_CONST));
117 f(ir_bk_bswap, "bswap64", make_function_1_type(type_int64_t, type_int64_t, DM_CONST));
118 f(ir_bk_clz, "clz", make_function_1_type(type_int, type_unsigned_int, DM_CONST));
119 f(ir_bk_clz, "clzl", make_function_1_type(type_int, type_unsigned_long, DM_CONST));
120 f(ir_bk_clz, "clzll", make_function_1_type(type_int, type_unsigned_long_long, DM_CONST));
121 f(ir_bk_ctz, "ctz", make_function_1_type(type_int, type_unsigned_int, DM_CONST));
122 f(ir_bk_ctz, "ctzl", make_function_1_type(type_int, type_unsigned_long, DM_CONST));
123 f(ir_bk_ctz, "ctzll", make_function_1_type(type_int, type_unsigned_long_long, DM_CONST));
124 f(ir_bk_ffs, "ffs", make_function_1_type(type_int, type_unsigned_int, DM_CONST));
125 f(ir_bk_ffs, "ffsl", make_function_1_type(type_int, type_unsigned_long, DM_CONST));
126 f(ir_bk_ffs, "ffsll", make_function_1_type(type_int, type_unsigned_long_long, DM_CONST));
127 f(ir_bk_frame_address, "frame_address", make_function_1_type(type_void_ptr, type_unsigned_int, DM_NONE));
128 f(ir_bk_parity, "parity", make_function_1_type(type_int, type_unsigned_int, DM_CONST));
129 f(ir_bk_parity, "parityl", make_function_1_type(type_int, type_unsigned_long, DM_CONST));
130 f(ir_bk_parity, "parityll", make_function_1_type(type_int, type_unsigned_long_long, DM_CONST));
131 f(ir_bk_popcount, "popcount", make_function_1_type(type_int, type_unsigned_int, DM_CONST));
132 f(ir_bk_popcount, "popcountl", make_function_1_type(type_int, type_unsigned_long, DM_CONST));
133 f(ir_bk_popcount, "popcountll", make_function_1_type(type_int, type_unsigned_long_long, DM_CONST));
134 f(ir_bk_prefetch, "prefetch", make_function_1_type_variadic(type_float, type_void_ptr, DM_NONE));
135 f(ir_bk_return_address, "return_address", make_function_1_type(type_void_ptr, type_unsigned_int, DM_NONE));
136 f(ir_bk_trap, "trap", make_function_type(type_void, 0, NULL, DM_NORETURN));
138 entity_t *(*l)(const char*,type_t*) = create_gnu_builtin_libc;
139 l("abort", make_function_type(type_void, 0, NULL, DM_NORETURN));
140 l("abs", make_function_type(type_int, 1, (type_t *[]) { type_int }, DM_CONST));
141 l("fabs", make_function_type(type_double, 1, (type_t *[]) { type_double }, DM_CONST));
142 l("fabsf", make_function_type(type_float, 1, (type_t *[]) { type_float }, DM_CONST));
143 l("fabsl", make_function_type(type_long_double, 1, (type_t *[]) { type_long_double }, DM_CONST));
144 l("labs", make_function_type(type_long, 1, (type_t *[]) { type_long }, DM_CONST));
145 l("llabs", make_function_type(type_long_long, 1, (type_t *[]) { type_long_long }, DM_CONST));
146 l("memcpy", make_function_type(type_void_ptr, 3, (type_t *[]) { type_void_ptr_restrict, type_const_void_ptr_restrict, type_size_t }, DM_NONE));
147 l("memcmp", make_function_type(type_int, 3, (type_t *[]) { type_const_void_ptr, type_const_void_ptr, type_size_t }, DM_PURE));
148 l("memset", make_function_type(type_void_ptr, 3, (type_t *[]) { type_void_ptr, type_int, type_size_t }, DM_NONE));
149 l("memmove", make_function_type(type_void_ptr, 3, (type_t *[]) { type_void_ptr_restrict, type_const_void_ptr_restrict, type_size_t }, DM_NONE));
150 l("strcat", make_function_type(type_char_ptr, 2, (type_t *[]) { type_char_ptr_restrict, type_const_char_ptr_restrict }, DM_NONE));
151 l("strncat", make_function_type(type_char_ptr, 3, (type_t *[]) { type_char_ptr_restrict, type_const_char_ptr_restrict, type_size_t }, DM_NONE));
152 l("strlen", make_function_type(type_size_t, 1, (type_t *[]) { type_const_char_ptr }, DM_PURE));
153 l("strcmp", make_function_type(type_int, 2, (type_t *[]) { type_const_char_ptr, type_const_char_ptr }, DM_PURE));
154 l("strcpy", make_function_type(type_char_ptr, 2, (type_t *[]) { type_char_ptr_restrict, type_const_char_ptr_restrict }, DM_NONE));
155 l("stpcpy", make_function_type(type_char_ptr, 2, (type_t *[]) { type_char_ptr_restrict, type_const_char_ptr_restrict }, DM_NONE));
156 l("strncpy", make_function_type(type_char_ptr, 3, (type_t *[]) { type_char_ptr_restrict, type_const_char_ptr_restrict, type_size_t }, DM_NONE));
157 l("exit", make_function_type(type_void, 1, (type_t *[]) { type_int }, DM_NORETURN));
158 l("malloc", make_function_type(type_void_ptr, 1, (type_t *[]) { type_size_t }, DM_MALLOC));
160 entity_t *(*c)(const char*,unsigned,type_t*) = create_gnu_builtin_chk;
161 c("memcpy", 3, 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));
162 c("memset", 3, make_function_type(type_void_ptr, 4, (type_t *[]) { type_void_ptr, type_int, type_size_t, type_size_t }, DM_NONE));
163 c("memmove", 3, 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));
164 c("strcat", 2, make_function_type(type_char_ptr, 3, (type_t *[]) { type_char_ptr_restrict, type_const_char_ptr_restrict, type_size_t }, DM_NONE));
165 c("strncat", 3, 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));
166 c("strcpy", 2, make_function_type(type_char_ptr, 3, (type_t *[]) { type_char_ptr_restrict, type_const_char_ptr_restrict, type_size_t }, DM_NONE));
167 c("stpcpy", 2, make_function_type(type_char_ptr, 3, (type_t *[]) { type_char_ptr_restrict, type_const_char_ptr_restrict, type_size_t }, DM_NONE));
168 c("strncpy", 3, 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));
170 /* TODO: gcc has a LONG list of builtin functions (nearly everything from
171 * C89-C99 and others. Complete this */
174 static entity_t *create_intrinsic_firm(ir_builtin_kind kind, const char *name,
177 symbol_t *symbol = symbol_table_insert(name);
178 entity_t *entity = create_builtin_function(BUILTIN_FIRM, symbol, type);
179 entity->function.b.firm_builtin_kind = kind;
183 static entity_t *create_intrinsic(builtin_kind_t kind, const char *name,
186 symbol_t *symbol = symbol_table_insert(name);
187 entity_t *entity = create_builtin_function(kind, symbol, type);
191 void create_microsoft_intrinsics(void)
193 entity_t *(*i)(builtin_kind_t,const char*,type_t*) = create_intrinsic;
194 entity_t *(*f)(ir_builtin_kind,const char*,type_t*) = create_intrinsic_firm;
195 /* intrinsics for all architectures */
196 i(BUILTIN_ROTL, "_rotl", make_function_2_type(type_unsigned_int, type_unsigned_int, type_int, DM_CONST));
197 i(BUILTIN_ROTL, "_rotl64", make_function_2_type(type_unsigned_int64, type_unsigned_int64, type_int, DM_CONST));
198 i(BUILTIN_ROTR, "_rotr", make_function_2_type(type_unsigned_int, type_unsigned_int, type_int, DM_CONST));
199 i(BUILTIN_ROTR, "_rotr64", make_function_2_type(type_unsigned_int64, type_unsigned_int64, type_int, DM_CONST));
201 f(ir_bk_bswap, "_byteswap_ushort", make_function_1_type(type_unsigned_short, type_unsigned_short, DM_CONST));
202 f(ir_bk_bswap, "_byteswap_ulong", make_function_1_type(type_unsigned_long, type_unsigned_long, DM_CONST));
203 f(ir_bk_bswap, "_byteswap_uint64", make_function_1_type(type_unsigned_int64, type_unsigned_int64, DM_CONST));
205 f(ir_bk_debugbreak, "__debugbreak", make_function_0_type(type_void, DM_NONE));
206 f(ir_bk_return_address, "_ReturnAddress", make_function_0_type(type_void_ptr, DM_NONE));
207 f(ir_bk_popcount, "__popcount", make_function_1_type(type_unsigned_int, type_unsigned_int, DM_CONST));
210 f(ir_bk_inport, "__inbyte", make_function_1_type(type_unsigned_char, type_unsigned_short, DM_NONE));
211 f(ir_bk_inport, "__inword", make_function_1_type(type_unsigned_short, type_unsigned_short, DM_NONE));
212 f(ir_bk_inport, "__indword", make_function_1_type(type_unsigned_long, type_unsigned_short, DM_NONE));
213 f(ir_bk_outport, "__outbyte", make_function_2_type(type_void, type_unsigned_short, type_unsigned_char, DM_NONE));
214 f(ir_bk_outport, "__outword", make_function_2_type(type_void, type_unsigned_short, type_unsigned_short, DM_NONE));
215 f(ir_bk_outport, "__outdword", make_function_2_type(type_void, type_unsigned_short, type_unsigned_long, DM_NONE));
216 f(ir_bk_trap, "__ud2", make_function_type(type_void, 0, NULL, DM_NORETURN));
219 static type_t *add_type_modifier(type_t *orig_type, decl_modifiers_t modifiers)
221 type_t *type = skip_typeref(orig_type);
223 assert(type->kind == TYPE_FUNCTION);
224 if ((type->function.modifiers & modifiers) == modifiers)
227 type_t *new_type = duplicate_type(type);
228 new_type->function.modifiers |= modifiers;
229 return identify_new_type(new_type);
232 void adapt_special_functions(function_t *function)
234 symbol_t *symbol = function->base.base.symbol;
237 const char *name = symbol->string;
239 /* the following list of names is taken from gcc (calls.c) */
241 /* Disregard prefix _, __, __x or __builtin_. */
242 if (name[0] == '_') {
243 if (strstart(name + 1, "_builtin_"))
245 else if (name[1] == '_' && name[2] == 'x')
247 else if (name[1] == '_')
253 if (name[0] == 's') {
254 if ((name[1] == 'e' && (streq(name, "setjmp")
255 || streq(name, "setjmp_syscall")))
256 || (name[1] == 'i' && streq(name, "sigsetjmp"))
257 || (name[1] == 'a' && streq(name, "savectx"))) {
259 = add_type_modifier(function->base.type, DM_RETURNS_TWICE);
260 } else if (name[1] == 'i' && streq(name, "siglongjmp")) {
262 = add_type_modifier(function->base.type, DM_NORETURN);
264 } else if ((name[0] == 'q' && streq(name, "qsetjmp"))
265 || (name[0] == 'v' && streq(name, "vfork"))
266 || (name[0] == 'g' && streq(name, "getcontext"))) {
268 = add_type_modifier(function->base.type, DM_RETURNS_TWICE);
269 } else if (name[0] == 'l' && streq(name, "longjmp")) {
271 = add_type_modifier(function->base.type, DM_NORETURN);