diff options
| author | Pekka Enberg <penberg@kernel.org> | 2011-10-25 12:26:30 +0300 |
|---|---|---|
| committer | Pekka Enberg <penberg@kernel.org> | 2011-10-28 13:45:42 +0300 |
| commit | bc367edabaf2503a20dfdd5f5912d9a4733424fa (patch) | |
| tree | fa2338fd05707c30bf849b387a570e5865fa2111 | |
| parent | ac1601d50ff22e2a4835ca252722ef687c7ef6d8 (diff) | |
| download | sparse-dev-bc367edabaf2503a20dfdd5f5912d9a4733424fa.tar.gz | |
sparse, llvm: Add support for union types
This patch adds support for SYM_UNION in symbol_type(). The LLVM API does not
provide support for unions so we treat them as opaque structs.
Cc: Christopher Li <sparse@chrisli.org>
Cc: Jeff Garzik <jgarzik@redhat.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Pekka Enberg <penberg@kernel.org>
| -rw-r--r-- | sparse-llvm.c | 20 | ||||
| -rw-r--r-- | validation/backend/union.c | 12 |
2 files changed, 32 insertions, 0 deletions
diff --git a/sparse-llvm.c b/sparse-llvm.c index a678d9cb..7f46c8a2 100644 --- a/sparse-llvm.c +++ b/sparse-llvm.c @@ -80,6 +80,23 @@ static LLVMTypeRef sym_struct_type(LLVMModuleRef module, struct symbol *sym) return ret; } +static LLVMTypeRef sym_union_type(LLVMModuleRef module, struct symbol *sym) +{ + LLVMTypeRef elements; + unsigned union_size; + + /* + * There's no union support in the LLVM API so we treat unions as + * opaque structs. The downside is that we lose type information on the + * members but as LLVM doesn't care, neither do we. + */ + union_size = sym->bit_size / 8; + + elements = LLVMArrayType(LLVMInt8Type(), union_size); + + return LLVMStructType(&elements, 1, 0 /* packed? */); +} + static LLVMTypeRef sym_ptr_type(LLVMModuleRef module, struct symbol *sym) { LLVMTypeRef type = symbol_type(module, sym->ctype.base_type); @@ -146,6 +163,9 @@ static LLVMTypeRef symbol_type(LLVMModuleRef module, struct symbol *sym) case SYM_PTR: ret = sym_ptr_type(module, sym); break; + case SYM_UNION: + ret = sym_union_type(module, sym); + break; case SYM_STRUCT: ret = sym_struct_type(module, sym); break; diff --git a/validation/backend/union.c b/validation/backend/union.c new file mode 100644 index 00000000..e155f6ad --- /dev/null +++ b/validation/backend/union.c @@ -0,0 +1,12 @@ +union foo { + unsigned long x; + unsigned char y; + char buf[128]; +}; + +static union foo foo; + +/* + * check-name: Union code generation + * check-command: ./sparsec -c $file -o tmp.o + */ |
