diff options
author | Alon Zakai <alonzakai@gmail.com> | 2011-08-14 21:55:00 -0700 |
---|---|---|
committer | Alon Zakai <alonzakai@gmail.com> | 2011-08-14 21:55:00 -0700 |
commit | bae64f351185d457d6dd7e4e7c7208eb3a25169d (patch) | |
tree | f63bcb9c7833d661da2b964ce9d63ffb6d6fd3e8 | |
parent | 80e978c04c8d23626c7edc63897b3dd44cd24f26 (diff) |
fix bug with storing aggregates
-rw-r--r-- | src/parseTools.js | 5 | ||||
-rw-r--r-- | tests/cases/storestruct.ll | 84 | ||||
-rw-r--r-- | tests/cases/storestruct.txt | 3 |
3 files changed, 92 insertions, 0 deletions
diff --git a/src/parseTools.js b/src/parseTools.js index 5c746de0..6eb95593 100644 --- a/src/parseTools.js +++ b/src/parseTools.js @@ -730,6 +730,11 @@ function makeSetValue(ptr, pos, value, type, noNeedFirst, ignore) { if (isStructType(type)) { var typeData = Types.types[type]; var ret = []; + // We can receive either an object - an object literal that was in the .ll - or a string, + // which is the ident of an aggregate struct + if (typeof value === 'string') { + value = range(typeData.fields.length).map(function(i) { return value + '.f' + i }); + } for (var i = 0; i < typeData.fields.length; i++) { ret.push(makeSetValue(ptr, pos + typeData.flatIndexes[i], value[i], typeData.fields[i], noNeedFirst)); } diff --git a/tests/cases/storestruct.ll b/tests/cases/storestruct.ll new file mode 100644 index 00000000..15022e2f --- /dev/null +++ b/tests/cases/storestruct.ll @@ -0,0 +1,84 @@ +; ModuleID = '/dev/shm/tmp/src.cpp.o' +target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:32:32-n8:16:32" +target triple = "i386-pc-linux-gnu" + +; Load and store an entire structure as a whole (and also load as a whole, extract values and save separately, etc.) + +%struct.X = type { i32, i32 } + +@.str = private unnamed_addr constant [9 x i8] c"*%d,%d*\0A\00" ; [#uses=1] + +; [#uses=0] +define i32 @main() { +entry: + %retval = alloca i32, align 4 ; [#uses=1] + %x = alloca %struct.X, align 4 ; [#uses=2] + %y = alloca %struct.X, align 4 ; [#uses=2] + store i32 0, i32* %retval + call void @llvm.dbg.declare(metadata !{%struct.X* %x}, metadata !6), !dbg !13 + call void @llvm.dbg.declare(metadata !{%struct.X* %y}, metadata !14), !dbg !15 + %a = getelementptr inbounds %struct.X* %x, i32 0, i32 0, !dbg !16 ; [#uses=1] + store i32 5, i32* %a, align 4, !dbg !16 + %b = getelementptr inbounds %struct.X* %x, i32 0, i32 1, !dbg !17 ; [#uses=1] + store i32 22, i32* %b, align 4, !dbg !17 + + %allx = load %struct.X* %x, align 4, !dbg !13 ; [#uses=1] + store %struct.X %allx, %struct.X* %y, align 4, !dbg !15 + + %a1 = getelementptr inbounds %struct.X* %y, i32 0, i32 0, !dbg !18 ; [#uses=1] + %tmp = load i32* %a1, align 4, !dbg !18 ; [#uses=1] + %b2 = getelementptr inbounds %struct.X* %y, i32 0, i32 1, !dbg !18 ; [#uses=1] + %tmp3 = load i32* %b2, align 4, !dbg !18 ; [#uses=1] + %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([9 x i8]* @.str, i32 0, i32 0), i32 %tmp, i32 %tmp3), !dbg !18 ; [#uses=0] + + store i32 7, i32* %a, align 4, !dbg !16 + store i32 96, i32* %b, align 4, !dbg !17 + %allx2 = load %struct.X* %x, align 4, !dbg !13 ; [#uses=1] + + %x_a = extractvalue %struct.X %allx2, 0 ; [#uses=1] + store i32 %x_a, i32* %a1, align 4 + %x_b = extractvalue %struct.X %allx2, 1 ; [#uses=1] + store i32 %x_b, i32* %b2, align 4 + + %tmp5 = load i32* %a1, align 4, !dbg !18 ; [#uses=1] + %tmp6 = load i32* %b2, align 4, !dbg !18 ; [#uses=1] + %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([9 x i8]* @.str, i32 0, i32 0), i32 %tmp5, i32 %tmp6), !dbg !18 ; [#uses=0] + + %ptr = inttoptr i32 52 to i32* ; [#uses=1] + store %struct.X { i32 ptrtoint (i32* getelementptr inbounds (i32* %ptr, i32 1, i32 0) to i32), i32 3 }, %struct.X* %y, align 4 ; store entire struct at once + + %tmp5 = load i32* %a1, align 4, !dbg !18 ; [#uses=1] + %tmp6 = load i32* %b2, align 4, !dbg !18 ; [#uses=1] + %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([9 x i8]* @.str, i32 0, i32 0), i32 %tmp5, i32 %tmp6), !dbg !18 ; [#uses=0] + + ret i32 0, !dbg !19 +} + +; [#uses=2] +declare void @llvm.dbg.declare(metadata, metadata) nounwind readnone + +; [#uses=1] +declare i32 @printf(i8*, ...) + +!llvm.dbg.sp = !{!0} + +!0 = metadata !{i32 589870, i32 0, metadata !1, metadata !"main", metadata !"main", metadata !"", metadata !1, i32 5, metadata !3, i1 false, i1 true, i32 0, i32 0, i32 0, i32 256, i1 false, i32 ()* @main} ; [ DW_TAG_subprogram ] +!1 = metadata !{i32 589865, metadata !"/dev/shm/tmp/src.cpp", metadata !"/dev/shm/tmp", metadata !2} ; [ DW_TAG_file_type ] +!2 = metadata !{i32 589841, i32 0, i32 4, metadata !"/dev/shm/tmp/src.cpp", metadata !"/dev/shm/tmp", metadata !"clang version 2.9 (tags/RELEASE_29/final)", i1 true, i1 false, metadata !"", i32 0} ; [ DW_TAG_compile_unit ] +!3 = metadata !{i32 589845, metadata !1, metadata !"", metadata !1, i32 0, i64 0, i64 0, i32 0, i32 0, i32 0, metadata !4, i32 0, i32 0} ; [ DW_TAG_subroutine_type ] +!4 = metadata !{metadata !5} +!5 = metadata !{i32 589860, metadata !2, metadata !"int", null, i32 0, i64 32, i64 32, i64 0, i32 0, i32 5} ; [ DW_TAG_base_type ] +!6 = metadata !{i32 590080, metadata !7, metadata !"x", metadata !1, i32 6, metadata !8, i32 0} ; [ DW_TAG_auto_variable ] +!7 = metadata !{i32 589835, metadata !0, i32 5, i32 11, metadata !1, i32 0} ; [ DW_TAG_lexical_block ] +!8 = metadata !{i32 589826, metadata !2, metadata !"X", metadata !1, i32 3, i64 64, i64 32, i32 0, i32 0, null, metadata !9, i32 0, null, metadata !12} ; [ DW_TAG_class_type ] +!9 = metadata !{metadata !10, metadata !11} +!10 = metadata !{i32 589837, metadata !1, metadata !"a", metadata !1, i32 3, i64 32, i64 32, i64 0, i32 0, metadata !5} ; [ DW_TAG_member ] +!11 = metadata !{i32 589837, metadata !1, metadata !"b", metadata !1, i32 3, i64 32, i64 32, i64 32, i32 0, metadata !5} ; [ DW_TAG_member ] +!12 = metadata !{i32 0} +!13 = metadata !{i32 6, i32 3, metadata !7, null} +!14 = metadata !{i32 590080, metadata !7, metadata !"y", metadata !1, i32 6, metadata !8, i32 0} ; [ DW_TAG_auto_variable ] +!15 = metadata !{i32 6, i32 6, metadata !7, null} +!16 = metadata !{i32 7, i32 1, metadata !7, null} +!17 = metadata !{i32 8, i32 1, metadata !7, null} +!18 = metadata !{i32 9, i32 13, metadata !7, null} +!19 = metadata !{i32 10, i32 13, metadata !7, null} diff --git a/tests/cases/storestruct.txt b/tests/cases/storestruct.txt new file mode 100644 index 00000000..e52a6bf5 --- /dev/null +++ b/tests/cases/storestruct.txt @@ -0,0 +1,3 @@ +*5,22* +*7,96* +*56,3* |