diff options
author | Pekka Enberg <penberg@kernel.org> | 2011-09-07 17:36:40 +0300 |
---|---|---|
committer | Pekka Enberg <penberg@kernel.org> | 2011-09-07 20:18:55 +0300 |
commit | f567535353119eae0e57beef52a83519e0ebee3e (patch) | |
tree | 500e1544d80cdb57809121b0c94d8e902f1e5497 | |
parent | 6d233957ef292a9552b7dba126eb1a66ff1ef9cd (diff) | |
download | sparse-f567535353119eae0e57beef52a83519e0ebee3e.tar.gz |
sparse, llvm: Add support for struct types
Signed-off-by: Pekka Enberg <penberg@kernel.org>
-rw-r--r-- | sparse-llvm.c | 55 | ||||
-rw-r--r-- | validation/backend/struct.c | 17 |
2 files changed, 70 insertions, 2 deletions
diff --git a/sparse-llvm.c b/sparse-llvm.c index 608d3a42..f1c99dd3 100644 --- a/sparse-llvm.c +++ b/sparse-llvm.c @@ -32,7 +32,33 @@ static inline bool symbol_is_fp_type(struct symbol *sym) return sym->ctype.base_type == &fp_type; } -static LLVMTypeRef symbol_type(struct symbol *sym) +static LLVMTypeRef symbol_type(struct symbol *sym); + +#define MAX_STRUCT_MEMBERS 64 + +static LLVMTypeRef sym_struct_type(struct symbol *sym) +{ + LLVMTypeRef elem_types[MAX_STRUCT_MEMBERS]; + struct symbol *member; + unsigned nr = 0; + + FOR_EACH_PTR(sym->symbol_list, member) { + assert(nr < MAX_STRUCT_MEMBERS); + + elem_types[nr++] = symbol_type(member); + } END_FOR_EACH_PTR(member); + + return LLVMStructType(elem_types, nr, 0 /* packed? */); +} + +static LLVMTypeRef sym_ptr_type(struct symbol *sym) +{ + LLVMTypeRef type = symbol_type(sym->ctype.base_type); + + return LLVMPointerType(type, 0); +} + +static LLVMTypeRef sym_basetype_type(struct symbol *sym) { LLVMTypeRef ret = NULL; @@ -77,6 +103,29 @@ static LLVMTypeRef symbol_type(struct symbol *sym) return ret; } +static LLVMTypeRef symbol_type(struct symbol *sym) +{ + LLVMTypeRef ret = NULL; + + switch (sym->type) { + case SYM_NODE: + ret = symbol_type(sym->ctype.base_type); + break; + case SYM_BASETYPE: + ret = sym_basetype_type(sym); + break; + case SYM_PTR: + ret = sym_ptr_type(sym); + break; + case SYM_STRUCT: + ret = sym_struct_type(sym); + break; + default: + assert(0); + } + return ret; +} + static LLVMTypeRef insn_symbol_type(struct instruction *insn) { if (insn->type) @@ -902,7 +951,9 @@ static int output_data(LLVMModuleRef module, struct symbol *sym) else assert(0); } else { - initial_value = LLVMConstInt(symbol_type(sym), 0, 1); + LLVMTypeRef type = symbol_type(sym); + + initial_value = LLVMConstNull(type); } name = show_ident(sym->ident); diff --git a/validation/backend/struct.c b/validation/backend/struct.c new file mode 100644 index 00000000..ef7d0d7e --- /dev/null +++ b/validation/backend/struct.c @@ -0,0 +1,17 @@ +struct ctype { + int type; +}; + +struct symbol { + void *p; + const char *name; + struct ctype ctype; +}; + +static struct symbol sym; +static struct symbol *sym_p; + +/* + * check-name: Struct code generation + * check-command: ./sparsec -c $file -o tmp.o + */ |