summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorLuc Van Oostenryck <luc.vanoostenryck@gmail.com>2018-06-21 12:09:53 +0200
committerLuc Van Oostenryck <luc.vanoostenryck@gmail.com>2018-12-17 21:56:29 +0100
commit749f0c51d1da0d89202cbbeba4b261994b4391f9 (patch)
tree3de5067b6b730f15f30ace066aeff76ad88415fb
parent9b2e1eb4be1b31cf580243b48add6e74cc5b5148 (diff)
downloadsparse-749f0c51d1da0d89202cbbeba4b261994b4391f9.tar.gz
give a type to wchar
This allows to use predefined_ctype() on wchar_t. Note: currently __WCHAR_TYPE__ is defined to 'int' but this is incorrect on: i386, m68k, ppc32, ... Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
-rw-r--r--char.c4
-rw-r--r--lib.c6
-rw-r--r--lib.h1
-rw-r--r--symbol.h1
-rw-r--r--target.c31
-rw-r--r--target.h3
6 files changed, 37 insertions, 9 deletions
diff --git a/char.c b/char.c
index c52521bc..f26b2a80 100644
--- a/char.c
+++ b/char.c
@@ -84,7 +84,7 @@ void get_char_constant(struct token *token, unsigned long long *val)
end = p + type - TOKEN_WIDE_CHAR;
}
p = parse_escape(p, &v, end,
- type < TOKEN_WIDE_CHAR ? bits_in_char : bits_in_wchar, token->pos);
+ type < TOKEN_WIDE_CHAR ? bits_in_char : wchar_ctype->bit_size, token->pos);
if (p != end)
warning(token->pos,
"multi-character character constant");
@@ -113,7 +113,7 @@ struct token *get_string_constant(struct token *token, struct expression *expr)
done = next;
}
}
- bits = is_wide ? bits_in_wchar : bits_in_char;
+ bits = is_wide ? wchar_ctype->bit_size: bits_in_char;
while (token != done) {
unsigned v;
const char *p = token->string->data;
diff --git a/lib.c b/lib.c
index 147c0729..e1970d89 100644
--- a/lib.c
+++ b/lib.c
@@ -317,6 +317,7 @@ static enum { STANDARD_C89,
int arch_m64 = ARCH_M64_DEFAULT;
int arch_msize_long = 0;
int arch_big_endian = ARCH_BIG_ENDIAN;
+int arch_mach = MACH_NATIVE;
#define CMDLINE_INCLUDE 20
@@ -1224,14 +1225,12 @@ static void predefined_macros(void)
break;
}
- predefined_sizeof("WCHAR", "_T", bits_in_wchar);
- predefined_max("WCHAR", "", bits_in_wchar);
- predefined_width("WCHAR", bits_in_wchar);
predefine("__CHAR_BIT__", 1, "%d", bits_in_char);
predefined_ctype("SHORT", &short_ctype, PTYPE_SIZEOF);
predefined_ctype("SHRT", &short_ctype, PTYPE_MAX|PTYPE_WIDTH);
predefined_ctype("SCHAR", &schar_ctype, PTYPE_MAX|PTYPE_WIDTH);
+ predefined_ctype("WCHAR", wchar_ctype, PTYPE_ALL_T|PTYPE_TYPE);
predefined_ctype("INT", &int_ctype, PTYPE_ALL);
predefined_ctype("LONG", &long_ctype, PTYPE_ALL);
@@ -1408,6 +1407,7 @@ struct symbol_list *sparse_initialize(int argc, char **argv, struct string_list
list = NULL;
if (filelist) {
// Initialize type system
+ init_target();
init_ctype();
predefined_macros();
diff --git a/lib.h b/lib.h
index cde74e93..a97e70b6 100644
--- a/lib.h
+++ b/lib.h
@@ -196,6 +196,7 @@ extern int funsigned_char;
extern int arch_m64;
extern int arch_msize_long;
extern int arch_big_endian;
+extern int arch_mach;
extern void dump_macro_definitions(void);
extern struct symbol_list *sparse_initialize(int argc, char **argv, struct string_list **files);
diff --git a/symbol.h b/symbol.h
index f9fb4bc5..287be628 100644
--- a/symbol.h
+++ b/symbol.h
@@ -303,6 +303,7 @@ extern void init_symbols(void);
extern void init_builtins(int stream);
extern void declare_builtins(void);
extern void init_ctype(void);
+extern void init_target(void);
extern struct symbol *alloc_symbol(struct position, int type);
extern void show_type(struct symbol *);
extern const char *modifier_string(unsigned long mod);
diff --git a/target.c b/target.c
index 86a9e2e6..a12b314e 100644
--- a/target.c
+++ b/target.c
@@ -2,9 +2,11 @@
#include "symbol.h"
#include "target.h"
+#include "machine.h"
struct symbol *size_t_ctype = &uint_ctype;
struct symbol *ssize_t_ctype = &int_ctype;
+struct symbol *wchar_ctype = &int_ctype;
/*
* For "__attribute__((aligned))"
@@ -22,8 +24,6 @@ int bits_in_long = 32;
int bits_in_longlong = 64;
int bits_in_longlonglong = 128;
-int bits_in_wchar = 32;
-
int max_int_alignment = 4;
/*
@@ -46,3 +46,30 @@ int pointer_alignment = 4;
*/
int bits_in_enum = 32;
int enum_alignment = 4;
+
+
+void init_target(void)
+{
+ switch (arch_mach) {
+ case MACH_X86_64:
+ if (arch_m64 == ARCH_LP64)
+ break;
+ /* fall through */
+ case MACH_I386:
+ case MACH_M68K:
+ case MACH_SPARC32:
+ case MACH_PPC32:
+ wchar_ctype = &long_ctype;
+ break;
+ case MACH_ARM:
+ case MACH_ARM64:
+ wchar_ctype = &uint_ctype;
+ break;
+ default:
+ break;
+ }
+
+#if defined(__CYGWIN__)
+ wchar_ctype = &ushort_ctype;
+#endif
+}
diff --git a/target.h b/target.h
index 8326fa21..74f51ffe 100644
--- a/target.h
+++ b/target.h
@@ -3,6 +3,7 @@
extern struct symbol *size_t_ctype;
extern struct symbol *ssize_t_ctype;
+extern struct symbol *wchar_ctype;
/*
* For "__attribute__((aligned))"
@@ -20,8 +21,6 @@ extern int bits_in_long;
extern int bits_in_longlong;
extern int bits_in_longlonglong;
-extern int bits_in_wchar;
-
extern int max_int_alignment;
/*