diff options
| -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 + */ |
