yihanaa created this revision. yihanaa added reviewers: rsmith, erichkeane, aaron.ballman. yihanaa added a project: clang. Herald added a project: All. yihanaa requested review of this revision. Herald added a subscriber: cfe-commits.
Thanks for @rsmith to point this. I'm sorry for introducing this bug. See @rsmith 's comment in https://reviews.llvm.org/D122248 Eg:(By @rsmith ) https://godbolt.org/z/o7vcbWaEf I have added a test case struct: struct U19A { int a; }; struct U19B { struct U19A a; }; struct U19B a = { .a.a = 2022 }; Dump result: struct U19B { struct U19A a = { int a = 2022 } } Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D122920 Files: clang/lib/CodeGen/CGBuiltin.cpp clang/test/CodeGen/dump-struct-builtin.c
Index: clang/test/CodeGen/dump-struct-builtin.c =================================================================== --- clang/test/CodeGen/dump-struct-builtin.c +++ clang/test/CodeGen/dump-struct-builtin.c @@ -5,95 +5,122 @@ // CHECK: @__const.unit1.a = private unnamed_addr constant %struct.U1A { i16 12 }, align 2 // CHECK-NEXT: [[STRUCT_STR_U1:@[0-9]+]] = private unnamed_addr constant [14 x i8] c"struct U1A {\0A\00", align 1 -// CHECK-NEXT: [[FIELD_U1:@[0-9]+]] = private unnamed_addr constant [19 x i8] c" short a = %hd\0A\00", align 1 +// CHECK-NEXT: [[FIELD_U1:@[0-9]+]] = private unnamed_addr constant [15 x i8] c" short a = \00", align 1 +// CHECK-NEXT: [[FORMAT_U1:@[0-9]+]] = private unnamed_addr constant [5 x i8] c"%hd\0A\00", align 1 // CHECK-NEXT: [[END_STRUCT_U1:@[0-9]+]] = private unnamed_addr constant [3 x i8] c"}\0A\00", align 1 // CHECK: @__const.unit2.a = private unnamed_addr constant %struct.U2A { i16 12 }, align 2 // CHECK-NEXT: [[STRUCT_STR_U2:@[0-9]+]] = private unnamed_addr constant [14 x i8] c"struct U2A {\0A\00", align 1 -// CHECK-NEXT: [[FIELD_U2:@[0-9]+]] = private unnamed_addr constant [28 x i8] c" unsigned short a = %hu\0A\00", align 1 +// CHECK-NEXT: [[FIELD_U2:@[0-9]+]] = private unnamed_addr constant [24 x i8] c" unsigned short a = \00", align 1 +// CHECK-NEXT: [[FORMAT_U2:@[0-9]+]] = private unnamed_addr constant [5 x i8] c"%hu\0A\00", align 1 // CHECK-NEXT: [[END_STRUCT_U2:@[0-9]+]] = private unnamed_addr constant [3 x i8] c"}\0A\00", align 1 // CHECK: @__const.unit3.a = private unnamed_addr constant %struct.U3A { i32 12 }, align 4 // CHECK-NEXT: [[STRUCT_STR_U3:@[0-9]+]] = private unnamed_addr constant [14 x i8] c"struct U3A {\0A\00", align 1 -// CHECK-NEXT: [[FIELD_U3:@[0-9]+]] = private unnamed_addr constant [16 x i8] c" int a = %d\0A\00", align 1 +// CHECK-NEXT: [[FIELD_U3:@[0-9]+]] = private unnamed_addr constant [13 x i8] c" int a = \00", align 1 +// CHECK-NEXT: [[FORMAT_U3:@[0-9]+]] = private unnamed_addr constant [4 x i8] c"%d\0A\00", align 1 // CHECK-NEXT: [[END_STRUCT_U3:@[0-9]+]] = private unnamed_addr constant [3 x i8] c"}\0A\00", align 1 // CHECK: @__const.unit4.a = private unnamed_addr constant %struct.U4A { i32 12 }, align 4 // CHECK-NEXT: [[STRUCT_STR_U4:@[0-9]+]] = private unnamed_addr constant [14 x i8] c"struct U4A {\0A\00", align 1 -// CHECK-NEXT: [[FIELD_U4:@[0-9]+]] = private unnamed_addr constant [25 x i8] c" unsigned int a = %u\0A\00", align 1 +// CHECK-NEXT: [[FIELD_U4:@[0-9]+]] = private unnamed_addr constant [22 x i8] c" unsigned int a = \00", align 1 +// CHECK-NEXT: [[FORMAT_U4:@[0-9]+]] = private unnamed_addr constant [4 x i8] c"%u\0A\00", align 1 // CHECK-NEXT: [[END_STRUCT_U4:@[0-9]+]] = private unnamed_addr constant [3 x i8] c"}\0A\00", align 1 // CHECK: @__const.unit5.a = private unnamed_addr constant %struct.U5A { i64 12 }, align 8 // CHECK-NEXT: [[STRUCT_STR_U5:@[0-9]+]] = private unnamed_addr constant [14 x i8] c"struct U5A {\0A\00", align 1 -// CHECK-NEXT: [[FIELD_U5:@[0-9]+]] = private unnamed_addr constant [18 x i8] c" long a = %ld\0A\00", align 1 +// CHECK-NEXT: [[FIELD_U5:@[0-9]+]] = private unnamed_addr constant [14 x i8] c" long a = \00", align 1 +// CHECK-NEXT: [[FORMAT_U5:@[0-9]+]] = private unnamed_addr constant [5 x i8] c"%ld\0A\00", align 1 // CHECK-NEXT: [[END_STRUCT_U5:@[0-9]+]] = private unnamed_addr constant [3 x i8] c"}\0A\00", align 1 // CHECK: @__const.unit6.a = private unnamed_addr constant %struct.U6A { i64 12 }, align 8 // CHECK-NEXT: [[STRUCT_STR_U6:@[0-9]+]] = private unnamed_addr constant [14 x i8] c"struct U6A {\0A\00", align 1 -// CHECK-NEXT: [[FIELD_U6:@[0-9]+]] = private unnamed_addr constant [27 x i8] c" unsigned long a = %lu\0A\00", align 1 +// CHECK-NEXT: [[FIELD_U6:@[0-9]+]] = private unnamed_addr constant [23 x i8] c" unsigned long a = \00", align 1 +// CHECK-NEXT: [[FORMAT_U6:@[0-9]+]] = private unnamed_addr constant [5 x i8] c"%lu\0A\00", align 1 // CHECK-NEXT: [[END_STRUCT_U6:@[0-9]+]] = private unnamed_addr constant [3 x i8] c"}\0A\00", align 1 // CHECK: @__const.unit7.a = private unnamed_addr constant %struct.U7A { i64 12 }, align 8 // CHECK-NEXT: [[STRUCT_STR_U7:@[0-9]+]] = private unnamed_addr constant [14 x i8] c"struct U7A {\0A\00", align 1 -// CHECK-NEXT: [[FIELD_U7:@[0-9]+]] = private unnamed_addr constant [24 x i8] c" long long a = %lld\0A\00", align 1 +// CHECK-NEXT: [[FIELD_U7:@[0-9]+]] = private unnamed_addr constant [19 x i8] c" long long a = \00", align 1 +// CHECK-NEXT: [[FORMAT_U7:@[0-9]+]] = private unnamed_addr constant [6 x i8] c"%lld\0A\00", align 1 // CHECK-NEXT: [[END_STRUCT_U7:@[0-9]+]] = private unnamed_addr constant [3 x i8] c"}\0A\00", align 1 // CHECK: @__const.unit8.a = private unnamed_addr constant %struct.U8A { i64 12 }, align 8 // CHECK-NEXT: [[STRUCT_STR_U8:@[0-9]+]] = private unnamed_addr constant [14 x i8] c"struct U8A {\0A\00", align 1 -// CHECK-NEXT: [[FIELD_U8:@[0-9]+]] = private unnamed_addr constant [33 x i8] c" unsigned long long a = %llu\0A\00", align 1 +// CHECK-NEXT: [[FIELD_U8:@[0-9]+]] = private unnamed_addr constant [28 x i8] c" unsigned long long a = \00", align 1 +// CHECK-NEXT: [[FORMAT_U8:@[0-9]+]] = private unnamed_addr constant [6 x i8] c"%llu\0A\00", align 1 // CHECK-NEXT: [[END_STRUCT_U8:@[0-9]+]] = private unnamed_addr constant [3 x i8] c"}\0A\00", align 1 // CHECK: @__const.unit9.a = private unnamed_addr constant %struct.U9A { i8 97 }, align 1 // CHECK-NEXT: [[STRUCT_STR_U9:@[0-9]+]] = private unnamed_addr constant [14 x i8] c"struct U9A {\0A\00", align 1 -// CHECK-NEXT: [[FIELD_U9:@[0-9]+]] = private unnamed_addr constant [17 x i8] c" char a = %c\0A\00", align 1 +// CHECK-NEXT: [[FIELD_U9:@[0-9]+]] = private unnamed_addr constant [14 x i8] c" char a = \00", align 1 +// CHECK-NEXT: [[FORMAT_U9:@[0-9]+]] = private unnamed_addr constant [4 x i8] c"%c\0A\00", align 1 // CHECK-NEXT: [[END_STRUCT_U9:@[0-9]+]] = private unnamed_addr constant [3 x i8] c"}\0A\00", align 1 // CHECK: @.str = private unnamed_addr constant [4 x i8] c"LSE\00", align 1 // CHECK: @__const.unit10.a = private unnamed_addr constant %struct.U10A { i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i32 0, i32 0) }, align 8 // CHECK-NEXT: [[STRUCT_STR_U10:@[0-9]+]] = private unnamed_addr constant [15 x i8] c"struct U10A {\0A\00", align 1 -// CHECK-NEXT: [[FIELD_U10:@[0-9]+]] = private unnamed_addr constant [19 x i8] c" char * a = %s\0A\00", align 1 +// CHECK-NEXT: [[FIELD_U10:@[0-9]+]] = private unnamed_addr constant [16 x i8] c" char * a = \00", align 1 +// CHECK-NEXT: [[FORMAT_U10:@[0-9]+]] = private unnamed_addr constant [4 x i8] c"%s\0A\00", align 1 // CHECK-NEXT: [[END_STRUCT_U10:@[0-9]+]] = private unnamed_addr constant [3 x i8] c"}\0A\00", align 1 // CHECK: @__const.unit11.a = private unnamed_addr constant %struct.U11A { i8* inttoptr (i64 305419896 to i8*) }, align 8 // CHECK-NEXT: [[STRUCT_STR_U11:@[0-9]+]] = private unnamed_addr constant [15 x i8] c"struct U11A {\0A\00", align 1 -// CHECK-NEXT: [[FIELD_U11:@[0-9]+]] = private unnamed_addr constant [19 x i8] c" void * a = %p\0A\00", align 1 +// CHECK-NEXT: [[FIELD_U11:@[0-9]+]] = private unnamed_addr constant [16 x i8] c" void * a = \00", align 1 +// CHECK-NEXT: [[FORMAT_U11:@[0-9]+]] = private unnamed_addr constant [4 x i8] c"%p\0A\00", align 1 // CHECK-NEXT: [[END_STRUCT_U11:@[0-9]+]] = private unnamed_addr constant [3 x i8] c"}\0A\00", align 1 // CHECK: @__const.unit12.a = private unnamed_addr constant %struct.U12A { i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i32 0, i32 0) }, align 8 // CHECK-NEXT: [[STRUCT_STR_U12:@[0-9]+]] = private unnamed_addr constant [15 x i8] c"struct U12A {\0A\00", align 1 -// CHECK-NEXT: [[FIELD_U12:@[0-9]+]] = private unnamed_addr constant [25 x i8] c" const char * a = %s\0A\00", align 1 +// CHECK-NEXT: [[FIELD_U12:@[0-9]+]] = private unnamed_addr constant [22 x i8] c" const char * a = \00", align 1 +// CHECK-NEXT: [[FORMAT_U12:@[0-9]+]] = private unnamed_addr constant [4 x i8] c"%s\0A\00", align 1 // CHECK-NEXT: [[END_STRUCT_U12:@[0-9]+]] = private unnamed_addr constant [3 x i8] c"}\0A\00", align 1 // CHECK: @__const.unit13.a = private unnamed_addr constant %struct.U13A { i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i32 0, i32 0) }, align 8 // CHECK-NEXT: [[STRUCT_STR_U13:@[0-9]+]] = private unnamed_addr constant [15 x i8] c"struct U13A {\0A\00", align 1 -// CHECK-NEXT: [[FIELD_U13:@[0-9]+]] = private unnamed_addr constant [27 x i8] c" const charstar a = %s\0A\00", align 1 +// CHECK-NEXT: [[FIELD_U13:@[0-9]+]] = private unnamed_addr constant [24 x i8] c" const charstar a = \00", align 1 +// CHECK-NEXT: [[FORMAT_U13:@[0-9]+]] = private unnamed_addr constant [4 x i8] c"%s\0A\00", align 1 // CHECK-NEXT: [[END_STRUCT_U13:@[0-9]+]] = private unnamed_addr constant [3 x i8] c"}\0A\00", align 1 // CHECK: @__const.unit14.a = private unnamed_addr constant %struct.U14A { double 0x3FF1F9ACFFA7EB6C }, align 8 // CHECK-NEXT: [[STRUCT_STR_U14:@[0-9]+]] = private unnamed_addr constant [15 x i8] c"struct U14A {\0A\00", align 1 -// CHECK-NEXT: [[FIELD_U14:@[0-9]+]] = private unnamed_addr constant [19 x i8] c" double a = %f\0A\00", align 1 +// CHECK-NEXT: [[FIELD_U14:@[0-9]+]] = private unnamed_addr constant [16 x i8] c" double a = \00", align 1 +// CHECK-NEXT: [[FORMAT_U14:@[0-9]+]] = private unnamed_addr constant [4 x i8] c"%f\0A\00", align 1 // CHECK-NEXT: [[END_STRUCT_U14:@[0-9]+]] = private unnamed_addr constant [3 x i8] c"}\0A\00", align 1 // CHECK: @__const.unit15.a = private unnamed_addr constant %struct.U15A { [3 x i32] [i32 1, i32 2, i32 3] }, align 4 // CHECK-NEXT: [[STRUCT_STR_U15:@[0-9]+]] = private unnamed_addr constant [15 x i8] c"struct U15A {\0A\00", align 1 -// CHECK-NEXT: [[FIELD_U15:@[0-9]+]] = private unnamed_addr constant [19 x i8] c" int[3] a = %p\0A\00", align 1 +// CHECK-NEXT: [[FIELD_U15:@[0-9]+]] = private unnamed_addr constant [16 x i8] c" int[3] a = \00", align 1 +// CHECK-NEXT: [[FORMAT_U15:@[0-9]+]] = private unnamed_addr constant [4 x i8] c"%p\0A\00", align 1 // CHECK-NEXT: [[END_STRUCT_U15:@[0-9]+]] = private unnamed_addr constant [3 x i8] c"}\0A\00", align 1 // CHECK: @__const.unit16.a = private unnamed_addr constant %struct.U16A { i8 12 }, align 1 // CHECK-NEXT: [[STRUCT_STR_U16:@[0-9]+]] = private unnamed_addr constant [15 x i8] c"struct U16A {\0A\00", align 1 -// CHECK-NEXT: [[FIELD_U16:@[0-9]+]] = private unnamed_addr constant [22 x i8] c" uint8_t a = %hhu\0A\00", align 1 +// CHECK-NEXT: [[FIELD_U16:@[0-9]+]] = private unnamed_addr constant [17 x i8] c" uint8_t a = \00", align 1 +// CHECK-NEXT: [[FORMAT_U16:@[0-9]+]] = private unnamed_addr constant [6 x i8] c"%hhu\0A\00", align 1 // CHECK-NEXT: [[END_STRUCT_U16:@[0-9]+]] = private unnamed_addr constant [3 x i8] c"}\0A\00", align 1 // CHECK: @__const.unit17.a = private unnamed_addr constant %struct.U17A { i8 12 }, align 1 // CHECK-NEXT: [[STRUCT_STR_U17:@[0-9]+]] = private unnamed_addr constant [15 x i8] c"struct U17A {\0A\00", align 1 -// CHECK-NEXT: [[FIELD_U17:@[0-9]+]] = private unnamed_addr constant [21 x i8] c" int8_t a = %hhd\0A\00", align 1 +// CHECK-NEXT: [[FIELD_U17:@[0-9]+]] = private unnamed_addr constant [16 x i8] c" int8_t a = \00", align 1 +// CHECK-NEXT: [[FORMAT_U17:@[0-9]+]] = private unnamed_addr constant [6 x i8] c"%hhd\0A\00", align 1 // CHECK-NEXT: [[END_STRUCT_U17:@[0-9]+]] = private unnamed_addr constant [3 x i8] c"}\0A\00", align 1 // CHECK: @__const.unit18.a = private unnamed_addr constant %struct.U18A { x86_fp80 0xK3FFF8FCD67FD3F5B6000 }, align 16 // CHECK-NEXT: [[STRUCT_STR_U18:@[0-9]+]] = private unnamed_addr constant [15 x i8] c"struct U18A {\0A\00", align 1 -// CHECK-NEXT: [[FIELD_U18:@[0-9]+]] = private unnamed_addr constant [25 x i8] c" long double a = %Lf\0A\00", align 1 +// CHECK-NEXT: [[FIELD_U18:@[0-9]+]] = private unnamed_addr constant [21 x i8] c" long double a = \00", align 1 +// CHECK-NEXT: [[FORMAT_U18:@[0-9]+]] = private unnamed_addr constant [5 x i8] c"%Lf\0A\00", align 1 // CHECK-NEXT: [[END_STRUCT_U18:@[0-9]+]] = private unnamed_addr constant [3 x i8] c"}\0A\00", align 1 +// CHECK: @__const.unit19.a = private unnamed_addr constant %struct.U19B { %struct.U19A { i32 2022 } }, align 4 +// CHECK-NEXT: [[STRUCT_STR_U19:@[0-9]+]] = private unnamed_addr constant [15 x i8] c"struct U19B {\0A\00", align 1 +// CHECK-NEXT: [[FIELD_U19:@[0-9]+]] = private unnamed_addr constant [21 x i8] c" struct U19A a = \00", align 1 +// CHECK-NEXT: [[NESTED_STRUCT_STR_U19:@[0-9]+]] = private unnamed_addr constant [3 x i8] c"{\0A\00", align 1 +// CHECK-NEXT: [[NESTED_FIELD_U19:@[0-9]+]] = private unnamed_addr constant [17 x i8] c" int a = \00", align 1 +// CHECK-NEXT: [[NESTED_FORMAT_U19:@[0-9]+]] = private unnamed_addr constant [4 x i8] c"%d\0A\00", align 1 +// CHECK-NEXT: [[END_NESTED_STRUCT_U19:@[0-9]+]] = private unnamed_addr constant [7 x i8] c" }\0A\00", align 1 +// CHECK-NEXT: [[END_STRUCT_U19:@[0-9]+]] = private unnamed_addr constant [3 x i8] c"}\0A\00", align 1 + int printf(const char *fmt, ...) { return 0; } @@ -107,9 +134,10 @@ .a = 12, }; // CHECK: call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([14 x i8], [14 x i8]* [[STRUCT_STR_U1]], i32 0, i32 0)) + // CHECK: call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([15 x i8], [15 x i8]* [[FIELD_U1]], i32 0, i32 0)) // CHECK: [[RES1:%.*]] = getelementptr inbounds %struct.U1A, %struct.U1A* %a, i32 0, i32 0 // CHECK: [[LOAD1:%.*]] = load i16, i16* [[RES1]], - // CHECK: call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([19 x i8], [19 x i8]* [[FIELD_U1]], i32 0, i32 0), i16 [[LOAD1]]) + // CHECK: call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([5 x i8], [5 x i8]* [[FORMAT_U1]], i32 0, i32 0), i16 [[LOAD1]]) // CHECK: call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([3 x i8], [3 x i8]* [[END_STRUCT_U1]], i32 0, i32 0)) __builtin_dump_struct(&a, &printf); } @@ -124,9 +152,10 @@ }; // CHECK: call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([14 x i8], [14 x i8]* [[STRUCT_STR_U2]], i32 0, i32 0)) + // CHECK: call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([24 x i8], [24 x i8]* [[FIELD_U2]], i32 0, i32 0)) // CHECK: [[RES1:%.*]] = getelementptr inbounds %struct.U2A, %struct.U2A* %a, i32 0, i32 0 // CHECK: [[LOAD1:%.*]] = load i16, i16* [[RES1]], - // CHECK: call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([28 x i8], [28 x i8]* [[FIELD_U2]], i32 0, i32 0), i16 [[LOAD1]]) + // CHECK: call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([5 x i8], [5 x i8]* [[FORMAT_U2]], i32 0, i32 0), i16 [[LOAD1]]) // CHECK: call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([3 x i8], [3 x i8]* [[END_STRUCT_U2]], i32 0, i32 0)) __builtin_dump_struct(&a, &printf); } @@ -141,9 +170,10 @@ }; // CHECK: call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([14 x i8], [14 x i8]* [[STRUCT_STR_U3]], i32 0, i32 0)) + // CHECK: call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([13 x i8], [13 x i8]* [[FIELD_U3]], i32 0, i32 0)) // CHECK: [[RES1:%.*]] = getelementptr inbounds %struct.U3A, %struct.U3A* %a, i32 0, i32 0 // CHECK: [[LOAD1:%.*]] = load i32, i32* [[RES1]], - // CHECK: call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([16 x i8], [16 x i8]* [[FIELD_U3]], i32 0, i32 0), i32 [[LOAD1]]) + // CHECK: call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* [[FORMAT_U3]], i32 0, i32 0), i32 [[LOAD1]]) // CHECK: call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([3 x i8], [3 x i8]* [[END_STRUCT_U3]], i32 0, i32 0) __builtin_dump_struct(&a, &printf); } @@ -158,9 +188,10 @@ }; // CHECK: call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([14 x i8], [14 x i8]* [[STRUCT_STR_U4]], i32 0, i32 0)) + // CHECK: call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([22 x i8], [22 x i8]* [[FIELD_U4]], i32 0, i32 0)) // CHECK: [[RES1:%.*]] = getelementptr inbounds %struct.U4A, %struct.U4A* %a, i32 0, i32 0 // CHECK: [[LOAD1:%.*]] = load i32, i32* [[RES1]], - // CHECK: call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([25 x i8], [25 x i8]* [[FIELD_U4]], i32 0, i32 0), i32 [[LOAD1]]) + // CHECK: call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* [[FORMAT_U4]], i32 0, i32 0), i32 [[LOAD1]]) // CHECK: call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([3 x i8], [3 x i8]* [[END_STRUCT_U4]], i32 0, i32 0) __builtin_dump_struct(&a, &printf); } @@ -175,9 +206,10 @@ }; // CHECK: call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([14 x i8], [14 x i8]* [[STRUCT_STR_U5]], i32 0, i32 0)) + // CHECK: call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([14 x i8], [14 x i8]* [[FIELD_U5]], i32 0, i32 0)) // CHECK: [[RES1:%.*]] = getelementptr inbounds %struct.U5A, %struct.U5A* %a, i32 0, i32 0 // CHECK: [[LOAD1:%.*]] = load i64, i64* [[RES1]], - // CHECK: call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([18 x i8], [18 x i8]* [[FIELD_U5]], i32 0, i32 0), i64 [[LOAD1]]) + // CHECK: call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([5 x i8], [5 x i8]* [[FORMAT_U5]], i32 0, i32 0), i64 [[LOAD1]]) // CHECK: call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([3 x i8], [3 x i8]* [[END_STRUCT_U5]], i32 0, i32 0) __builtin_dump_struct(&a, &printf); } @@ -192,9 +224,10 @@ }; // CHECK: call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([14 x i8], [14 x i8]* [[STRUCT_STR_U6]], i32 0, i32 0)) + // CHECK: call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([23 x i8], [23 x i8]* [[FIELD_U6]], i32 0, i32 0)) // CHECK: [[RES1:%.*]] = getelementptr inbounds %struct.U6A, %struct.U6A* %a, i32 0, i32 0 // CHECK: [[LOAD1:%.*]] = load i64, i64* [[RES1]], - // CHECK: call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([27 x i8], [27 x i8]* [[FIELD_U6]], i32 0, i32 0), i64 [[LOAD1]]) + // CHECK: call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([5 x i8], [5 x i8]* [[FORMAT_U6]], i32 0, i32 0), i64 [[LOAD1]]) // CHECK: call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([3 x i8], [3 x i8]* [[END_STRUCT_U6]], i32 0, i32 0) __builtin_dump_struct(&a, &printf); } @@ -209,9 +242,10 @@ }; // CHECK: call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([14 x i8], [14 x i8]* [[STRUCT_STR_U7]], i32 0, i32 0)) + // CHECK: call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([19 x i8], [19 x i8]* [[FIELD_U7]], i32 0, i32 0)) // CHECK: [[RES1:%.*]] = getelementptr inbounds %struct.U7A, %struct.U7A* %a, i32 0, i32 0 // CHECK: [[LOAD1:%.*]] = load i64, i64* [[RES1]], - // CHECK: call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([24 x i8], [24 x i8]* [[FIELD_U7]], i32 0, i32 0), i64 [[LOAD1]]) + // CHECK: call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([6 x i8], [6 x i8]* [[FORMAT_U7]], i32 0, i32 0), i64 [[LOAD1]]) // CHECK: call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([3 x i8], [3 x i8]* [[END_STRUCT_U7]], i32 0, i32 0) __builtin_dump_struct(&a, &printf); } @@ -226,9 +260,10 @@ }; // CHECK: call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([14 x i8], [14 x i8]* [[STRUCT_STR_U8]], i32 0, i32 0)) + // CHECK: call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([28 x i8], [28 x i8]* [[FIELD_U8]], i32 0, i32 0)) // CHECK: [[RES1:%.*]] = getelementptr inbounds %struct.U8A, %struct.U8A* %a, i32 0, i32 0 // CHECK: [[LOAD1:%.*]] = load i64, i64* [[RES1]], - // CHECK: call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([33 x i8], [33 x i8]* [[FIELD_U8]], i32 0, i32 0), i64 [[LOAD1]]) + // CHECK: call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([6 x i8], [6 x i8]* [[FORMAT_U8]], i32 0, i32 0), i64 [[LOAD1]]) // CHECK: call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([3 x i8], [3 x i8]* [[END_STRUCT_U8]], i32 0, i32 0) __builtin_dump_struct(&a, &printf); } @@ -243,9 +278,10 @@ }; // CHECK: call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([14 x i8], [14 x i8]* [[STRUCT_STR_U9]], i32 0, i32 0)) + // CHECK: call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([14 x i8], [14 x i8]* [[FIELD_U9]], i32 0, i32 0)) // CHECK: [[RES1:%.*]] = getelementptr inbounds %struct.U9A, %struct.U9A* %a, i32 0, i32 0 // CHECK: [[LOAD1:%.*]] = load i8, i8* [[RES1]], - // CHECK: call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([17 x i8], [17 x i8]* [[FIELD_U9]], i32 0, i32 0), i8 [[LOAD1]]) + // CHECK: call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* [[FORMAT_U9]], i32 0, i32 0), i8 [[LOAD1]]) // CHECK: call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([3 x i8], [3 x i8]* [[END_STRUCT_U9]], i32 0, i32 0) __builtin_dump_struct(&a, &printf); } @@ -260,9 +296,10 @@ }; // CHECK: call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([15 x i8], [15 x i8]* [[STRUCT_STR_U10]], i32 0, i32 0)) + // CHECK: call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([16 x i8], [16 x i8]* [[FIELD_U10]], i32 0, i32 0)) // CHECK: [[RES1:%.*]] = getelementptr inbounds %struct.U10A, %struct.U10A* %a, i32 0, i32 0 // CHECK: [[LOAD1:%.*]] = load i8*, i8** [[RES1]], - // CHECK: call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([19 x i8], [19 x i8]* [[FIELD_U10]], i32 0, i32 0), i8* [[LOAD1]]) + // CHECK: call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* [[FORMAT_U10]], i32 0, i32 0), i8* [[LOAD1]]) // CHECK: call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([3 x i8], [3 x i8]* [[END_STRUCT_U10]], i32 0, i32 0) __builtin_dump_struct(&a, &printf); } @@ -277,9 +314,10 @@ }; // CHECK: call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([15 x i8], [15 x i8]* [[STRUCT_STR_U11]], i32 0, i32 0)) + // CHECK: call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([16 x i8], [16 x i8]* [[FIELD_U11]], i32 0, i32 0)) // CHECK: [[RES1:%.*]] = getelementptr inbounds %struct.U11A, %struct.U11A* %a, i32 0, i32 0 // CHECK: [[LOAD1:%.*]] = load i8*, i8** [[RES1]], - // CHECK: call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([19 x i8], [19 x i8]* [[FIELD_U11]], i32 0, i32 0), i8* [[LOAD1]]) + // CHECK: call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* [[FORMAT_U11]], i32 0, i32 0), i8* [[LOAD1]]) // CHECK: call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([3 x i8], [3 x i8]* [[END_STRUCT_U11]], i32 0, i32 0) __builtin_dump_struct(&a, &printf); } @@ -294,9 +332,10 @@ }; // CHECK: call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([15 x i8], [15 x i8]* [[STRUCT_STR_U12]], i32 0, i32 0)) + // CHECK: call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([22 x i8], [22 x i8]* [[FIELD_U12]], i32 0, i32 0)) // CHECK: [[RES1:%.*]] = getelementptr inbounds %struct.U12A, %struct.U12A* %a, i32 0, i32 0 // CHECK: [[LOAD1:%.*]] = load i8*, i8** [[RES1]], - // CHECK: call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([25 x i8], [25 x i8]* [[FIELD_U12]], i32 0, i32 0), i8* [[LOAD1]]) + // CHECK: call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* [[FORMAT_U12]], i32 0, i32 0), i8* [[LOAD1]]) // CHECK: call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([3 x i8], [3 x i8]* [[END_STRUCT_U12]], i32 0, i32 0) __builtin_dump_struct(&a, &printf); } @@ -314,7 +353,7 @@ // CHECK: call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([15 x i8], [15 x i8]* [[STRUCT_STR_U13]], i32 0, i32 0)) // CHECK: [[RES1:%.*]] = getelementptr inbounds %struct.U13A, %struct.U13A* %a, i32 0, i32 0 // CHECK: [[LOAD1:%.*]] = load i8*, i8** [[RES1]], - // CHECK: call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([27 x i8], [27 x i8]* [[FIELD_U13]], i32 0, i32 0), i8* [[LOAD1]]) + // CHECK: call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* [[FORMAT_U13]], i32 0, i32 0), i8* [[LOAD1]]) // CHECK: call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([3 x i8], [3 x i8]* [[END_STRUCT_U13]], i32 0, i32 0) __builtin_dump_struct(&a, &printf); } @@ -329,9 +368,10 @@ }; // CHECK: call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([15 x i8], [15 x i8]* [[STRUCT_STR_U14]], i32 0, i32 0)) + // CHECK: call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([16 x i8], [16 x i8]* [[FIELD_U14]], i32 0, i32 0)) // CHECK: [[RES1:%.*]] = getelementptr inbounds %struct.U14A, %struct.U14A* %a, i32 0, i32 0 // CHECK: [[LOAD1:%.*]] = load double, double* [[RES1]], - // CHECK: call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([19 x i8], [19 x i8]* [[FIELD_U14]], i32 0, i32 0), double [[LOAD1]]) + // CHECK: call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* [[FORMAT_U14]], i32 0, i32 0), double [[LOAD1]]) // CHECK: call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([3 x i8], [3 x i8]* [[END_STRUCT_U14]], i32 0, i32 0) __builtin_dump_struct(&a, &printf); } @@ -346,9 +386,10 @@ }; // CHECK: call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([15 x i8], [15 x i8]* [[STRUCT_STR_U15]], i32 0, i32 0)) + // CHECK: call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([16 x i8], [16 x i8]* [[FIELD_U15]], i32 0, i32 0)) // CHECK: [[RES1:%.*]] = getelementptr inbounds %struct.U15A, %struct.U15A* %a, i32 0, i32 0 // CHECK: [[LOAD1:%.*]] = load [3 x i32], [3 x i32]* [[RES1]], - // CHECK: call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([19 x i8], [19 x i8]* [[FIELD_U15]], i32 0, i32 0), [3 x i32] [[LOAD1]]) + // CHECK: call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* [[FORMAT_U15]], i32 0, i32 0), [3 x i32] [[LOAD1]]) // CHECK: call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([3 x i8], [3 x i8]* [[END_STRUCT_U15]], i32 0, i32 0) __builtin_dump_struct(&a, &printf); } @@ -363,9 +404,10 @@ }; // CHECK: call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([15 x i8], [15 x i8]* [[STRUCT_STR_U16]], i32 0, i32 0)) + // CHECK: call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([17 x i8], [17 x i8]* [[FIELD_U16]], i32 0, i32 0)) // CHECK: [[RES1:%.*]] = getelementptr inbounds %struct.U16A, %struct.U16A* %a, i32 0, i32 0 // CHECK: [[LOAD1:%.*]] = load i8, i8* [[RES1]], - // CHECK: call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([22 x i8], [22 x i8]* [[FIELD_U16]], i32 0, i32 0), i8 [[LOAD1]]) + // CHECK: call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([6 x i8], [6 x i8]* [[FORMAT_U16]], i32 0, i32 0), i8 [[LOAD1]]) // CHECK: call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([3 x i8], [3 x i8]* [[END_STRUCT_U16]], i32 0, i32 0) __builtin_dump_struct(&a, &printf); } @@ -380,9 +422,10 @@ }; // CHECK: call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([15 x i8], [15 x i8]* [[STRUCT_STR_U17]], i32 0, i32 0)) + // CHECK: call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([16 x i8], [16 x i8]* [[FIELD_U17]], i32 0, i32 0)) // CHECK: [[RES1:%.*]] = getelementptr inbounds %struct.U17A, %struct.U17A* %a, i32 0, i32 0 // CHECK: [[LOAD1:%.*]] = load i8, i8* [[RES1]], - // CHECK: call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([21 x i8], [21 x i8]* [[FIELD_U17]], i32 0, i32 0), i8 [[LOAD1]]) + // CHECK: call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([6 x i8], [6 x i8]* [[FORMAT_U17]], i32 0, i32 0), i8 [[LOAD1]]) // CHECK: call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([3 x i8], [3 x i8]* [[END_STRUCT_U17]], i32 0, i32 0) __builtin_dump_struct(&a, &printf); } @@ -397,13 +440,41 @@ }; // CHECK: call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([15 x i8], [15 x i8]* [[STRUCT_STR_U18]], i32 0, i32 0)) + // CHECK: call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([21 x i8], [21 x i8]* [[FIELD_U18]], i32 0, i32 0)) // CHECK: [[RES1:%.*]] = getelementptr inbounds %struct.U18A, %struct.U18A* %a, i32 0, i32 0 // CHECK: [[LOAD1:%.*]] = load x86_fp80, x86_fp80* [[RES1]], - // CHECK: call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([25 x i8], [25 x i8]* [[FIELD_U18]], i32 0, i32 0), x86_fp80 [[LOAD1]]) + // CHECK: call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([5 x i8], [5 x i8]* [[FORMAT_U18]], i32 0, i32 0), x86_fp80 [[LOAD1]]) // CHECK: call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([3 x i8], [3 x i8]* [[END_STRUCT_U18]], i32 0, i32 0) __builtin_dump_struct(&a, &printf); } +void unit19(void) { + + struct U19A { + int a; + }; + + struct U19B { + struct U19A a; + }; + + struct U19B a = { + .a.a = 2022 + }; + + // CHECK: call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([15 x i8], [15 x i8]* [[STRUCT_STR_U19]], i32 0, i32 0)) + // CHECK: call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([21 x i8], [21 x i8]* [[FIELD_U19]], i32 0, i32 0)) + // CHECK: [[RES1:%.*]] = getelementptr inbounds %struct.U19B, %struct.U19B* %a, i32 0, i32 0 + // CHECK: call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([3 x i8], [3 x i8]* [[NESTED_STRUCT_STR_U19]], i32 0, i32 0)) + // CHECK: call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([17 x i8], [17 x i8]* [[NESTED_FIELD_U19]], i32 0, i32 0)) + // CHECK: [[RES2:%.*]] = getelementptr inbounds %struct.U19A, %struct.U19A* [[RES1]], i32 0, i32 0 + // CHECK: [[LOAD2:%.*]] = load i32, i32* [[RES2]], + // CHECK: call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* [[NESTED_FORMAT_U19]], i32 0, i32 0), i32 [[LOAD2]]) + // CHECK: call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([7 x i8], [7 x i8]* [[END_NESTED_STRUCT_U19]], i32 0, i32 0)) + // CHECK: call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([3 x i8], [3 x i8]* [[END_STRUCT_U19]], i32 0, i32 0)) + __builtin_dump_struct(&a, &printf); +} + void test1(void) { struct T1A { int a; @@ -415,10 +486,12 @@ .b = "LSE", }; + // CHECK: call i32 (i8*, ...) @printf( // CHECK: call i32 (i8*, ...) @printf( // CHECK: [[RES1:%.*]] = getelementptr inbounds %struct.T1A, %struct.T1A* %a, i32 0, i32 0 // CHECK: [[LOAD1:%.*]] = load i32, i32* [[RES1]], // CHECK: call i32 (i8*, ...) @printf({{.*}}, i32 [[LOAD1]]) + // CHECK: call i32 (i8*, ...) @printf( // CHECK: [[RES2:%.*]] = getelementptr inbounds %struct.T1A, %struct.T1A* %a, i32 0, i32 1 // CHECK: [[LOAD2:%.*]] = load i8*, i8** [[RES2]], // CHECK: call i32 (i8*, ...) @printf({{.*}}, i8* [[LOAD2]]) @@ -443,16 +516,20 @@ } }; + // CHECK: call i32 (i8*, ...) @printf( // CHECK: call i32 (i8*, ...) @printf( // CHECK: [[RES1:%.*]] = getelementptr inbounds %struct.T2B, %struct.T2B* %b, i32 0, i32 0 // CHECK: [[LOAD1:%.*]] = load i32, i32* [[RES1]], // CHECK: call i32 (i8*, ...) @printf({{.*}}, i32 [[LOAD1]]) + // CHECK: call i32 (i8*, ...) @printf( // CHECK: [[NESTED_STRUCT:%.*]] = getelementptr inbounds %struct.T2B, %struct.T2B* %b, i32 0, i32 1 // CHECK: call i32 (i8*, ...) @printf( + // CHECK: call i32 (i8*, ...) @printf( // CHECK: [[RES2:%.*]] = getelementptr inbounds %struct.T2A, %struct.T2A* [[NESTED_STRUCT]], i32 0, i32 0 // CHECK: [[LOAD2:%.*]] = load i32, i32* [[RES2]], // CHECK: call i32 (i8*, ...) @printf({{.*}}, i32 [[LOAD2]]) // CHECK: call i32 (i8*, ...) @printf( + // CHECK: call i32 (i8*, ...) @printf( __builtin_dump_struct(&b, &printf); } @@ -468,12 +545,15 @@ .a = 42, }; + // CHECK: call i32 (i8*, ...) @printf( // CHECK: call i32 (i8*, ...) @printf( // CHECK: [[RES1:%.*]] = getelementptr inbounds %struct.T3A, %struct.T3A* %a, i32 0, i32 0 // CHECK: call i32 (i8*, ...) @printf( + // CHECK: call i32 (i8*, ...) @printf( // CHECK: [[BC1:%.*]] = bitcast %union.anon* [[RES1]] to i32* // CHECK: [[LOAD1:%.*]] = load i32, i32* [[BC1]], // CHECK: call i32 (i8*, ...) @printf({{.*}}, i32 [[LOAD1]]) + // CHECK: call i32 (i8*, ...) @printf( // CHECK: [[BC2:%.*]] = bitcast %union.anon* [[RES1]] to [4 x i8]* // CHECK: [[LOAD2:%.*]] = load [4 x i8], [4 x i8]* [[BC2]], // CHECK: call i32 (i8*, ...) @printf({{.*}}, [4 x i8] [[LOAD2]]) @@ -498,17 +578,22 @@ .a = (void *)0x12345678, }; + // CHECK: call i32 (i8*, ...) @printf( // CHECK: call i32 (i8*, ...) @printf( // CHECK: [[RES1:%.*]] = getelementptr inbounds %struct.T4A, %struct.T4A* %a, i32 0, i32 0 // CHECK: call i32 (i8*, ...) @printf( + // CHECK: call i32 (i8*, ...) @printf( // CHECK: [[BC1:%.*]] = bitcast %union.anon.0* [[RES1]] to %struct.anon* // CHECK: call i32 (i8*, ...) @printf( + // CHECK: call i32 (i8*, ...) @printf( // CHECK: [[RES2:%.*]] = getelementptr inbounds %struct.anon, %struct.anon* [[BC1]], i32 0, i32 0 // CHECK: [[LOAD1:%.*]] = load i8*, i8** [[RES2]], // CHECK: call i32 (i8*, ...) @printf({{.*}}, i8* [[LOAD1]]) // CHECK: call i32 (i8*, ...) @printf( + // CHECK: call i32 (i8*, ...) @printf( // CHECK: [[BC2:%.*]] = bitcast %union.anon.0* [[RES1]] to %struct.anon.1* // CHECK: call i32 (i8*, ...) @printf( + // CHECK: call i32 (i8*, ...) @printf( // CHECK: [[RES3:%.*]] = getelementptr inbounds %struct.anon.1, %struct.anon.1* [[BC2]], i32 0, i32 0 // CHECK: [[LOAD2:%.*]] = load i64, i64* [[RES3]], // CHECK: call i32 (i8*, ...) @printf({{.*}}, i64 [[LOAD2]]) @@ -527,12 +612,13 @@ .a = 0, }; - // CHECK: call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([14 x i8], [14 x i8]* {{.*}}, i32 0, i32 0)) + // CHECK: call i32 (i8*, ...) @printf( + // CHECK: call i32 (i8*, ...) @printf( // CHECK: [[BC1:%.*]] = bitcast %struct.T5A* %a to i8* // CHECK: [[LOAD1:%.*]] = load i8, i8* [[BC1]], // CHECK: [[CLEAR1:%.*]] = and i8 [[LOAD1]], 1 // CHECK: [[CAST1:%.*]] = zext i8 [[CLEAR1]] to i32 - // CHECK: call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([29 x i8], [29 x i8]* {{.*}}, i32 0, i32 0), i32 [[CAST1]]) + // CHECK: call i32 (i8*, ...) @printf(i8* getelementptr inbounds ({{.*}}, i32 [[CAST1]]) // CHECK: call i32 (i8*, ...) @printf( __builtin_dump_struct(&a, &printf); } @@ -550,24 +636,27 @@ .c = 1, }; + // CHECK: call i32 (i8*, ...) @printf( // CHECK: call i32 (i8*, ...) @printf( // CHECK: [[BC1:%.*]] = bitcast %struct.T6A* %a to i8* // CHECK: [[LOAD1:%.*]] = load i8, i8* [[BC1]], // CHECK: [[CLEAR1:%.*]] = and i8 [[LOAD1]], 1 // CHECK: [[CAST1:%.*]] = zext i8 [[CLEAR1]] to i32 - // CHECK: call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([29 x i8], [29 x i8]* {{.*}}, i32 0, i32 0), i32 [[CAST1]]) + // CHECK: call i32 (i8*, ...) @printf(i8* getelementptr inbounds ({{.*}}, i32 [[CAST1]]) + // CHECK: call i32 (i8*, ...) @printf( // CHECK: [[BC2:%.*]] = bitcast %struct.T6A* %a to i8* // CHECK: [[LOAD2:%.*]] = load i8, i8* [[BC2]], align 4 // CHECK: [[LSHR2:%.*]] = lshr i8 [[LOAD2]], 1 // CHECK: [[CLEAR2:%.*]] = and i8 [[LSHR2]], 1 // CHECK: [[CAST2:%.*]] = zext i8 [[CLEAR2]] to i32 - // CHECK: call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([29 x i8], [29 x i8]* {{.*}}, i32 0, i32 0), i32 [[CAST2]]) + // CHECK: call i32 (i8*, ...) @printf(i8* getelementptr inbounds ({{.*}}, i32 [[CAST2]]) + // CHECK: call i32 (i8*, ...) @printf( // CHECK: [[BC3:%.*]] = bitcast %struct.T6A* %a to i8* // CHECK: [[LOAD3:%.*]] = load i8, i8* [[BC3]], align 4 // CHECK: [[LSHR3:%.*]] = lshr i8 [[LOAD3]], 2 // CHECK: [[CLEAR3:%.*]] = and i8 [[LSHR3]], 1 // CHECK: [[CAST3:%.*]] = zext i8 [[CLEAR3]] to i32 - // CHECK: call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([29 x i8], [29 x i8]* {{.*}}, i32 0, i32 0), i32 [[CAST3]]) + // CHECK: call i32 (i8*, ...) @printf(i8* getelementptr inbounds ({{.*}}, i32 [[CAST3]]) // CHECK: call i32 (i8*, ...) @printf( __builtin_dump_struct(&a, &printf); } @@ -588,20 +677,23 @@ .b = 1, }; + // CHECK: call i32 (i8*, ...) @printf( // CHECK: call i32 (i8*, ...) @printf( // CHECK: [[RES1:%.*]] = getelementptr inbounds %struct.T7B, %struct.T7B* %a, i32 0, i32 0 // CHECK: call i32 (i8*, ...) @printf( + // CHECK: call i32 (i8*, ...) @printf( // CHECK: [[BC1:%.*]] = bitcast %struct.T7A* [[RES1]] to i8* // CHECK: [[LOAD1:%.*]] = load i8, i8* [[BC1]], // CHECK: [[CLEAR1:%.*]] = and i8 [[LOAD1]], 1 // CHECK: [[CAST1:%.*]] = zext i8 [[CLEAR1]] to i32 - // CHECK: call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([33 x i8], [33 x i8]* {{.*}}, i32 0, i32 0), i32 [[CAST1]]) + // CHECK: call i32 (i8*, ...) @printf(i8* getelementptr inbounds ({{.*}}, i32 [[CAST1]]) + // CHECK: call i32 (i8*, ...) @printf( // CHECK: call i32 (i8*, ...) @printf( // CHECK: [[RES2:%.*]] = getelementptr inbounds %struct.T7B, %struct.T7B* %a, i32 0, i32 1 // CHECK: [[LOAD2:%.*]] = load i8, i8* [[RES2]], align 4 // CHECK: [[CLEAR2:%.*]] = and i8 [[LOAD2]], 1 // CHECK: [[CAST2:%.*]] = zext i8 [[CLEAR2]] to i32 - // CHECK: call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([29 x i8], [29 x i8]* {{.*}}, i32 0, i32 0), i32 [[CAST2]]) + // CHECK: call i32 (i8*, ...) @printf(i8* getelementptr inbounds ({{.*}}, i32 [[CAST2]]) // CHECK: call i32 (i8*, ...) @printf( __builtin_dump_struct(&a, &printf); } @@ -618,22 +710,25 @@ .b = 2022, }; + // CHECK: call i32 (i8*, ...) @printf( // CHECK: call i32 (i8*, ...) @printf( // CHECK: [[BC1:%.*]] = bitcast %struct.T8A* %a to i8* // CHECK: [[LOAD1:%.*]] = load i8, i8* [[BC1]], // CHECK: [[CLEAR1:%.*]] = and i8 [[LOAD1]], 1 // CHECK: [[CAST1:%.*]] = zext i8 [[CLEAR1]] to i32 - // CHECK: call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([29 x i8], [29 x i8]* {{.*}}, i32 0, i32 0), i32 [[CAST1]]) + // CHECK: call i32 (i8*, ...) @printf({{.*}}, i32 [[CAST1]]) + // CHECK: call i32 (i8*, ...) @printf( // CHECK: [[BC2:%.*]] = bitcast %struct.T8A* %a to i8* // CHECK: [[LOAD2:%.*]] = load i8, i8* [[BC2]], // CHECK: [[LSHR2:%.*]] = lshr i8 [[LOAD2]], 1 // CHECK: [[CLEAR2:%.*]] = and i8 [[LSHR2]], 7 // CHECK: [[CAST2:%.*]] = zext i8 [[CLEAR2]] to i32 - // CHECK: call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([27 x i8], [27 x i8]* {{.*}}, i32 0, i32 0), i32 [[CAST2]]) + // CHECK: call i32 (i8*, ...) @printf({{.*}}, i32 0, i32 0), i32 [[CAST2]]) + // CHECK: call i32 (i8*, ...) @printf( // CHECK: call i32 (i8*, ...) @printf( // CHECK: [[RES3:%.*]] = getelementptr inbounds %struct.T8A, %struct.T8A* %a, i32 0, i32 1 // CHECK: [[LOAD3:%.*]] = load i32, i32* [[RES3]], - // CHECK: call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([25 x i8], [25 x i8]* {{.*}}, i32 0, i32 0), i32 [[LOAD3]]) + // CHECK: call i32 (i8*, ...) @printf(i8* getelementptr inbounds ({{.*}}, i32 [[LOAD3]]) // CHECK: call i32 (i8*, ...) @printf( __builtin_dump_struct(&a, &printf); } Index: clang/lib/CodeGen/CGBuiltin.cpp =================================================================== --- clang/lib/CodeGen/CGBuiltin.cpp +++ clang/lib/CodeGen/CGBuiltin.cpp @@ -2044,17 +2044,23 @@ } static llvm::Value *dumpRecord(CodeGenFunction &CGF, QualType RType, - LValue RecordLV, CharUnits Align, - llvm::FunctionCallee Func, int Lvl) { + LValue RecordLV, CharUnits Align, + bool dumpTypeName, llvm::FunctionCallee Func, + int Lvl) { ASTContext &Context = CGF.getContext(); RecordDecl *RD = RType->castAs<RecordType>()->getDecl()->getDefinition(); std::string Pad = std::string(Lvl * 4, ' '); std::string ElementPad = std::string((Lvl + 1) * 4, ' '); - PrintingPolicy Policy(Context.getLangOpts()); - Policy.AnonymousTagLocations = false; - Value *GString = CGF.Builder.CreateGlobalStringPtr( - llvm::Twine(Pad).concat(RType.getAsString(Policy)).concat(" {\n").str()); + Value *GString = nullptr; + if (dumpTypeName) { + PrintingPolicy Policy(Context.getLangOpts()); + Policy.AnonymousTagLocations = false; + GString = CGF.Builder.CreateGlobalStringPtr( + llvm::Twine(Pad).concat(RType.getAsString(Policy)).concat(" {\n").str()); + } else { + GString = CGF.Builder.CreateGlobalStringPtr("{\n"); + } Value *Res = CGF.Builder.CreateCall(Func, {GString}); static llvm::DenseMap<QualType, const char *> Types; @@ -2108,25 +2114,38 @@ } } + GString = CGF.Builder.CreateGlobalStringPtr(llvm::Twine(Format) + .concat(" = ").str()); + TmpRes = CGF.Builder.CreateCall(Func, {GString}); + Res = CGF.Builder.CreateAdd(TmpRes, Res); + LValue FieldLV = CGF.EmitLValueForField(RecordLV, FD); QualType CanonicalType = FD->getType().getUnqualifiedType().getCanonicalType(); // We check whether we are in a recursive type if (CanonicalType->isRecordType()) { - TmpRes = dumpRecord(CGF, CanonicalType, FieldLV, Align, Func, Lvl + 1); + + // If current field is a record type, we should not dump the type name in + // recursive dumpRecord call. + // for example: + // ... + // struct Foo foo = { + // some fields... + // } + // ... + TmpRes = dumpRecord(CGF, CanonicalType, FieldLV, Align, false, Func, + Lvl + 1); Res = CGF.Builder.CreateAdd(TmpRes, Res); continue; } // We try to determine the best format to print the current field - const char *TypeFormat = Types.find(CanonicalType) == Types.end() + const char *TypeFormatSpec = Types.find(CanonicalType) == Types.end() ? Types[Context.VoidPtrTy] : Types[CanonicalType]; - GString = CGF.Builder.CreateGlobalStringPtr(llvm::Twine(Format) - .concat(" = ") - .concat(TypeFormat) + GString = CGF.Builder.CreateGlobalStringPtr(llvm::Twine(TypeFormatSpec) .concat(llvm::Twine('\n')) .str()); @@ -2681,7 +2700,7 @@ Value *RecordPtr = EmitScalarExpr(Arg0); LValue RecordLV = MakeAddrLValue(RecordPtr, Arg0Type, Arg0Align); - Value *Res = dumpRecord(*this, Arg0Type, RecordLV, Arg0Align, + Value *Res = dumpRecord(*this, Arg0Type, RecordLV, Arg0Align, true, {LLVMFuncType, Func}, 0); return RValue::get(Res); }
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits