1; RUN: llc < %s -filetype=obj | llvm-readobj - -codeview | FileCheck %s
2;
3; Command to generate function-options.ll
4; $ clang++ function-options.cpp -S -emit-llvm -g -gcodeview -o function-options.ll
5;
6;
7; #define DEFINE_FUNCTION(T) \
8;   T Func_##T(T &arg) { return arg; }
9;
10; class AClass {};
11; DEFINE_FUNCTION(AClass); // Expect: FO = None
12;
13; class BClass {
14; private:
15;   explicit BClass(); // Expect ctor: FO = Constructor
16; };
17; DEFINE_FUNCTION(BClass); // Expect: FO = CxxReturnUdt
18;
19; class C1Class {
20; public:
21;   C1Class() = default; // Note: Clang generates one defaulted ctor (FO = None) while MSVC doesn't.
22; };
23; DEFINE_FUNCTION(C1Class); // Expect: FO = None
24;
25; class C2Class { // Note: MSVC-specific dtor, i.e. __vecDelDtor won't be verified in this case.
26; public:
27;   ~C2Class() {} // Expect ~C2Class: FO = None
28; };
29; DEFINE_FUNCTION(C2Class); // Expect: FO = CxxReturnUdt
30;
31; class DClass : public BClass {}; // Note: MSVC yields one compiler-generated ctor for DClass while clang doesn't.
32; DEFINE_FUNCTION(DClass); // Expect: FO = CxxReturnUdt
33;
34; class FClass { static int x; };
35; DEFINE_FUNCTION(FClass); // Expect FO = None
36;
37; struct AStruct {};
38; DEFINE_FUNCTION(AStruct); // Expect FO = None
39;
40; struct BStruct { BStruct(); }; // Expect ctor: FO = Constructor
41; DEFINE_FUNCTION(BStruct); // Expect FO = CxxReturnUdt
42;
43; union AUnion {};
44; DEFINE_FUNCTION(AUnion); // Expect FO = None
45;
46; union BUnion { BUnion() = default; }; // Note: Clang generates one defaulted ctor (FO = None) while MSVC does not.
47; DEFINE_FUNCTION(BUnion); // Expect FO = None
48
49
50; CHECK: Format: COFF-x86-64
51; CHECK: Arch: x86_64
52; CHECK: AddressSize: 64bit
53; CHECK: CodeViewTypes [
54; CHECK:   Section: .debug$T ({{.*}})
55; CHECK:   Magic: 0x4
56; CHECK:   Procedure ([[SP1:.*]]) {
57; CHECK:     TypeLeafKind: LF_PROCEDURE (0x1008)
58; CHECK:     ReturnType: AClass ({{.*}})
59; CHECK:     CallingConvention: NearC (0x0)
60; CHECK:     FunctionOptions [ (0x0)
61; CHECK:     ]
62; CHECK:     NumParameters: 1
63; CHECK:     ArgListType: (AClass&) ({{.*}})
64; CHECK:   }
65; CHECK:   FuncId ({{.*}}) {
66; CHECK:     TypeLeafKind: LF_FUNC_ID (0x1601)
67; CHECK:     ParentScope: 0x0
68; CHECK:     FunctionType: AClass (AClass&) ([[SP1]])
69; CHECK:     Name: Func_AClass
70; CHECK:   }
71; CHECK:   Procedure ([[SP2:.*]]) {
72; CHECK:     TypeLeafKind: LF_PROCEDURE (0x1008)
73; CHECK:     ReturnType: BClass ({{.*}})
74; CHECK:     CallingConvention: NearC (0x0)
75; CHECK:     FunctionOptions [ (0x1)
76; CHECK:       CxxReturnUdt (0x1)
77; CHECK:     ]
78; CHECK:     NumParameters: 1
79; CHECK:     ArgListType: (BClass&) ({{.*}})
80; CHECK:   }
81; CHECK:   MemberFunction ([[MF1:.*]]) {
82; CHECK:     TypeLeafKind: LF_MFUNCTION (0x1009)
83; CHECK:     ReturnType: void (0x3)
84; CHECK:     ClassType: BClass ({{.*}})
85; CHECK:     ThisType: BClass* const ({{.*}})
86; CHECK:     CallingConvention: NearC (0x0)
87; CHECK:     FunctionOptions [ (0x2)
88; CHECK:       Constructor (0x2)
89; CHECK:     ]
90; CHECK:     NumParameters: 0
91; CHECK:     ArgListType: () ({{.*}})
92; CHECK:     ThisAdjustment: 0
93; CHECK:   }
94; CHECK:   FieldList ({{.*}}) {
95; CHECK:     TypeLeafKind: LF_FIELDLIST (0x1203)
96; CHECK:     OneMethod {
97; CHECK:       TypeLeafKind: LF_ONEMETHOD (0x1511)
98; CHECK:       AccessSpecifier: Private (0x1)
99; CHECK:       Type: void BClass::() ([[MF1]])
100; CHECK:       Name: BClass
101; CHECK:     }
102; CHECK:   }
103; CHECK:   FuncId ({{.*}}) {
104; CHECK:     TypeLeafKind: LF_FUNC_ID (0x1601)
105; CHECK:     ParentScope: 0x0
106; CHECK:     FunctionType: BClass (BClass&) ([[SP2]])
107; CHECK:     Name: Func_BClass
108; CHECK:   }
109; CHECK:   Procedure ([[SP3:.*]]) {
110; CHECK:     TypeLeafKind: LF_PROCEDURE (0x1008)
111; CHECK:     ReturnType: C1Class ({{.*}})
112; CHECK:     CallingConvention: NearC (0x0)
113; CHECK:     FunctionOptions [ (0x0)
114; CHECK:     ]
115; CHECK:     NumParameters: 1
116; CHECK:     ArgListType: (C1Class&) ({{.*}})
117; CHECK:   }
118; CHECK:   MemberFunction ([[MF2:.*]]) {
119; CHECK:     TypeLeafKind: LF_MFUNCTION (0x1009)
120; CHECK:     ReturnType: void (0x3)
121; CHECK:     ClassType: C1Class ({{.*}})
122; CHECK:     ThisType: C1Class* const ({{.*}})
123; CHECK:     CallingConvention: NearC (0x0)
124; CHECK:     FunctionOptions [ (0x0)
125; CHECK:     ]
126; CHECK:     NumParameters: 0
127; CHECK:     ArgListType: () ({{.*}})
128; CHECK:     ThisAdjustment: 0
129; CHECK:   }
130; CHECK:   FieldList ({{.*}}) {
131; CHECK:     TypeLeafKind: LF_FIELDLIST (0x1203)
132; CHECK:     OneMethod {
133; CHECK:       TypeLeafKind: LF_ONEMETHOD (0x1511)
134; CHECK:       AccessSpecifier: Public (0x3)
135; CHECK:       Type: void C1Class::() ([[MF2]])
136; CHECK:       Name: C1Class
137; CHECK:     }
138; CHECK:   }
139; CHECK:   FuncId ({{.*}}) {
140; CHECK:     TypeLeafKind: LF_FUNC_ID (0x1601)
141; CHECK:     ParentScope: 0x0
142; CHECK:     FunctionType: C1Class (C1Class&) ([[SP3]])
143; CHECK:     Name: Func_C1Class
144; CHECK:   }
145; CHECK:   Procedure ([[SP4:.*]]) {
146; CHECK:     TypeLeafKind: LF_PROCEDURE (0x1008)
147; CHECK:     ReturnType: C2Class ({{.*}})
148; CHECK:     CallingConvention: NearC (0x0)
149; CHECK:     FunctionOptions [ (0x1)
150; CHECK:       CxxReturnUdt (0x1)
151; CHECK:     ]
152; CHECK:     NumParameters: 1
153; CHECK:     ArgListType: (C2Class&) ({{.*}})
154; CHECK:   }
155; CHECK:   MemberFunction ([[MF3:.*]]) {
156; CHECK:     TypeLeafKind: LF_MFUNCTION (0x1009)
157; CHECK:     ReturnType: void (0x3)
158; CHECK:     ClassType: C2Class ({{.*}})
159; CHECK:     ThisType: C2Class* const ({{.*}})
160; CHECK:     CallingConvention: NearC (0x0)
161; CHECK:     FunctionOptions [ (0x0)
162; CHECK:     ]
163; CHECK:     NumParameters: 0
164; CHECK:     ArgListType: () ({{.*}})
165; CHECK:     ThisAdjustment: 0
166; CHECK:   }
167; CHECK:   FieldList ({{.*}}) {
168; CHECK:     TypeLeafKind: LF_FIELDLIST (0x1203)
169; CHECK:     OneMethod {
170; CHECK:       TypeLeafKind: LF_ONEMETHOD (0x1511)
171; CHECK:       AccessSpecifier: Public (0x3)
172; CHECK:       Type: void C2Class::() ([[MF3]])
173; CHECK:       Name: ~C2Class
174; CHECK:     }
175; CHECK:   }
176; CHECK:   FuncId ({{.*}}) {
177; CHECK:     TypeLeafKind: LF_FUNC_ID (0x1601)
178; CHECK:     ParentScope: 0x0
179; CHECK:     FunctionType: C2Class (C2Class&) ([[SP4]])
180; CHECK:     Name: Func_C2Class
181; CHECK:   }
182; CHECK:   Procedure ([[SP5:.*]]) {
183; CHECK:     TypeLeafKind: LF_PROCEDURE (0x1008)
184; CHECK:     ReturnType: DClass ({{.*}})
185; CHECK:     CallingConvention: NearC (0x0)
186; CHECK:     FunctionOptions [ (0x1)
187; CHECK:       CxxReturnUdt (0x1)
188; CHECK:     ]
189; CHECK:     NumParameters: 1
190; CHECK:     ArgListType: (DClass&) ({{.*}})
191; CHECK:   }
192; CHECK:   FieldList ({{.*}}) {
193; CHECK:     TypeLeafKind: LF_FIELDLIST (0x1203)
194; CHECK:     BaseClass {
195; CHECK:       TypeLeafKind: LF_BCLASS (0x1400)
196; CHECK:       AccessSpecifier: Public (0x3)
197; CHECK:       BaseType: BClass ({{.*}})
198; CHECK:       BaseOffset: 0x0
199; CHECK:     }
200; CHECK:   }
201; CHECK:   FuncId ({{.*}}) {
202; CHECK:     TypeLeafKind: LF_FUNC_ID (0x1601)
203; CHECK:     ParentScope: 0x0
204; CHECK:     FunctionType: DClass (DClass&) ([[SP5]])
205; CHECK:     Name: Func_DClass
206; CHECK:   }
207; CHECK:   Procedure ([[SP6:.*]]) {
208; CHECK:     TypeLeafKind: LF_PROCEDURE (0x1008)
209; CHECK:     ReturnType: FClass ({{.*}})
210; CHECK:     CallingConvention: NearC (0x0)
211; CHECK:     FunctionOptions [ (0x0)
212; CHECK:     ]
213; CHECK:     NumParameters: 1
214; CHECK:     ArgListType: (FClass&) ({{.*}})
215; CHECK:   }
216; CHECK:   FieldList ({{.*}}) {
217; CHECK:     TypeLeafKind: LF_FIELDLIST (0x1203)
218; CHECK:     StaticDataMember {
219; CHECK:       TypeLeafKind: LF_STMEMBER (0x150E)
220; CHECK:       AccessSpecifier: Private (0x1)
221; CHECK:       Type: int (0x74)
222; CHECK:       Name: x
223; CHECK:     }
224; CHECK:   }
225; CHECK:   FuncId ({{.*}}) {
226; CHECK:     TypeLeafKind: LF_FUNC_ID (0x1601)
227; CHECK:     ParentScope: 0x0
228; CHECK:     FunctionType: FClass (FClass&) ([[SP6]])
229; CHECK:     Name: Func_FClass
230; CHECK:   }
231; CHECK:   Procedure ([[SP7:.*]]) {
232; CHECK:     TypeLeafKind: LF_PROCEDURE (0x1008)
233; CHECK:     ReturnType: AStruct ({{.*}})
234; CHECK:     CallingConvention: NearC (0x0)
235; CHECK:     FunctionOptions [ (0x0)
236; CHECK:     ]
237; CHECK:     NumParameters: 1
238; CHECK:     ArgListType: (AStruct&) ({{.*}})
239; CHECK:   }
240; CHECK:   FuncId ({{.*}}) {
241; CHECK:     TypeLeafKind: LF_FUNC_ID (0x1601)
242; CHECK:     ParentScope: 0x0
243; CHECK:     FunctionType: AStruct (AStruct&) ([[SP7]])
244; CHECK:     Name: Func_AStruct
245; CHECK:   }
246; CHECK:   Procedure ([[SP8:.*]]) {
247; CHECK:     TypeLeafKind: LF_PROCEDURE (0x1008)
248; CHECK:     ReturnType: BStruct ({{.*}})
249; CHECK:     CallingConvention: NearC (0x0)
250; CHECK:     FunctionOptions [ (0x1)
251; CHECK:       CxxReturnUdt (0x1)
252; CHECK:     ]
253; CHECK:     NumParameters: 1
254; CHECK:     ArgListType: (BStruct&) ({{.*}})
255; CHECK:   }
256; CHECK:   MemberFunction ([[MF4:.*]]) {
257; CHECK:     TypeLeafKind: LF_MFUNCTION (0x1009)
258; CHECK:     ReturnType: void (0x3)
259; CHECK:     ClassType: BStruct ({{.*}})
260; CHECK:     ThisType: BStruct* const ({{.*}})
261; CHECK:     CallingConvention: NearC (0x0)
262; CHECK:     FunctionOptions [ (0x2)
263; CHECK:       Constructor (0x2)
264; CHECK:     ]
265; CHECK:     NumParameters: 0
266; CHECK:     ArgListType: () ({{.*}})
267; CHECK:     ThisAdjustment: 0
268; CHECK:   }
269; CHECK:   FieldList ({{.*}}) {
270; CHECK:     TypeLeafKind: LF_FIELDLIST (0x1203)
271; CHECK:     OneMethod {
272; CHECK:       TypeLeafKind: LF_ONEMETHOD (0x1511)
273; CHECK:       AccessSpecifier: Public (0x3)
274; CHECK:       Type: void BStruct::() ([[MF4]])
275; CHECK:       Name: BStruct
276; CHECK:     }
277; CHECK:   }
278; CHECK:   FuncId ({{.*}}) {
279; CHECK:     TypeLeafKind: LF_FUNC_ID (0x1601)
280; CHECK:     ParentScope: 0x0
281; CHECK:     FunctionType: BStruct (BStruct&) ([[SP8]])
282; CHECK:     Name: Func_BStruct
283; CHECK:   }
284; CHECK:   Procedure ([[SP9:.*]]) {
285; CHECK:     TypeLeafKind: LF_PROCEDURE (0x1008)
286; CHECK:     ReturnType: AUnion ({{.*}})
287; CHECK:     CallingConvention: NearC (0x0)
288; CHECK:     FunctionOptions [ (0x0)
289; CHECK:     ]
290; CHECK:     NumParameters: 1
291; CHECK:     ArgListType: (AUnion&) ({{.*}})
292; CHECK:   }
293; CHECK:   FuncId ({{.*}}) {
294; CHECK:     TypeLeafKind: LF_FUNC_ID (0x1601)
295; CHECK:     ParentScope: 0x0
296; CHECK:     FunctionType: AUnion (AUnion&) ([[SP9]])
297; CHECK:     Name: Func_AUnion
298; CHECK:   }
299; CHECK:   Procedure ([[SP10:.*]]) {
300; CHECK:     TypeLeafKind: LF_PROCEDURE (0x1008)
301; CHECK:     ReturnType: BUnion ({{.*}})
302; CHECK:     CallingConvention: NearC (0x0)
303; CHECK:     FunctionOptions [ (0x0)
304; CHECK:     ]
305; CHECK:     NumParameters: 1
306; CHECK:     ArgListType: (BUnion&) ({{.*}})
307; CHECK:   }
308; CHECK:   MemberFunction ([[MF5:.*]]) {
309; CHECK:     TypeLeafKind: LF_MFUNCTION (0x1009)
310; CHECK:     ReturnType: void (0x3)
311; CHECK:     ClassType: BUnion ({{.*}})
312; CHECK:     ThisType: BUnion* const ({{.*}})
313; CHECK:     CallingConvention: NearC (0x0)
314; CHECK:     FunctionOptions [ (0x0)
315; CHECK:     ]
316; CHECK:     NumParameters: 0
317; CHECK:     ArgListType: () ({{.*}})
318; CHECK:     ThisAdjustment: 0
319; CHECK:   }
320; CHECK:   FieldList ({{.*}}) {
321; CHECK:     TypeLeafKind: LF_FIELDLIST (0x1203)
322; CHECK:     OneMethod {
323; CHECK:       TypeLeafKind: LF_ONEMETHOD (0x1511)
324; CHECK:       AccessSpecifier: Public (0x3)
325; CHECK:       Type: void BUnion::() ([[MF5]])
326; CHECK:       Name: BUnion
327; CHECK:     }
328; CHECK:   }
329; CHECK:   FuncId ({{.*}}) {
330; CHECK:     TypeLeafKind: LF_FUNC_ID (0x1601)
331; CHECK:     ParentScope: 0x0
332; CHECK:     FunctionType: BUnion (BUnion&) ([[SP10]])
333; CHECK:     Name: Func_BUnion
334; CHECK:   }
335; CHECK: ]
336
337
338; ModuleID = 'function-options.cpp'
339source_filename = "function-options.cpp"
340target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128"
341target triple = "x86_64-pc-windows-msvc19.15.26729"
342
343%class.AClass = type { i8 }
344%class.BClass = type { i8 }
345%class.C1Class = type { i8 }
346%class.C2Class = type { i8 }
347%class.DClass = type { i8 }
348%class.FClass = type { i8 }
349%struct.AStruct = type { i8 }
350%struct.BStruct = type { i8 }
351%union.AUnion = type { i8 }
352%union.BUnion = type { i8 }
353
354; Function Attrs: noinline nounwind optnone uwtable
355define dso_local i8 @"?Func_AClass@@YA?AVAClass@@AEAV1@@Z"(%class.AClass* dereferenceable(1) %arg) #0 !dbg !8 {
356entry:
357  %retval = alloca %class.AClass, align 1
358  %arg.addr = alloca %class.AClass*, align 8
359  store %class.AClass* %arg, %class.AClass** %arg.addr, align 8
360  call void @llvm.dbg.declare(metadata %class.AClass** %arg.addr, metadata !14, metadata !DIExpression()), !dbg !15
361  %0 = load %class.AClass*, %class.AClass** %arg.addr, align 8, !dbg !15
362  %coerce.dive = getelementptr inbounds %class.AClass, %class.AClass* %retval, i32 0, i32 0, !dbg !15
363  %1 = load i8, i8* %coerce.dive, align 1, !dbg !15
364  ret i8 %1, !dbg !15
365}
366
367; Function Attrs: nounwind readnone speculatable
368declare void @llvm.dbg.declare(metadata, metadata, metadata) #1
369
370; Function Attrs: noinline nounwind optnone uwtable
371define dso_local void @"?Func_BClass@@YA?AVBClass@@AEAV1@@Z"(%class.BClass* noalias sret %agg.result, %class.BClass* dereferenceable(1) %arg) #0 !dbg !16 {
372entry:
373  %arg.addr = alloca %class.BClass*, align 8
374  store %class.BClass* %arg, %class.BClass** %arg.addr, align 8
375  call void @llvm.dbg.declare(metadata %class.BClass** %arg.addr, metadata !26, metadata !DIExpression()), !dbg !27
376  %0 = load %class.BClass*, %class.BClass** %arg.addr, align 8, !dbg !27
377  ret void, !dbg !27
378}
379
380; Function Attrs: noinline nounwind optnone uwtable
381define dso_local void @"?Func_C1Class@@YA?AVC1Class@@AEAV1@@Z"(%class.C1Class* noalias sret %agg.result, %class.C1Class* dereferenceable(1) %arg) #0 !dbg !28 {
382entry:
383  %arg.addr = alloca %class.C1Class*, align 8
384  store %class.C1Class* %arg, %class.C1Class** %arg.addr, align 8
385  call void @llvm.dbg.declare(metadata %class.C1Class** %arg.addr, metadata !38, metadata !DIExpression()), !dbg !39
386  %0 = load %class.C1Class*, %class.C1Class** %arg.addr, align 8, !dbg !39
387  ret void, !dbg !39
388}
389
390; Function Attrs: noinline nounwind optnone uwtable
391define dso_local void @"?Func_C2Class@@YA?AVC2Class@@AEAV1@@Z"(%class.C2Class* noalias sret %agg.result, %class.C2Class* dereferenceable(1) %arg) #0 !dbg !40 {
392entry:
393  %arg.addr = alloca %class.C2Class*, align 8
394  store %class.C2Class* %arg, %class.C2Class** %arg.addr, align 8
395  call void @llvm.dbg.declare(metadata %class.C2Class** %arg.addr, metadata !50, metadata !DIExpression()), !dbg !51
396  %0 = load %class.C2Class*, %class.C2Class** %arg.addr, align 8, !dbg !51
397  ret void, !dbg !51
398}
399
400; Function Attrs: noinline nounwind optnone uwtable
401define dso_local void @"?Func_DClass@@YA?AVDClass@@AEAV1@@Z"(%class.DClass* noalias sret %agg.result, %class.DClass* dereferenceable(1) %arg) #0 !dbg !52 {
402entry:
403  %arg.addr = alloca %class.DClass*, align 8
404  store %class.DClass* %arg, %class.DClass** %arg.addr, align 8
405  call void @llvm.dbg.declare(metadata %class.DClass** %arg.addr, metadata !59, metadata !DIExpression()), !dbg !60
406  %0 = load %class.DClass*, %class.DClass** %arg.addr, align 8, !dbg !60
407  ret void, !dbg !60
408}
409
410; Function Attrs: noinline nounwind optnone uwtable
411define dso_local i8 @"?Func_FClass@@YA?AVFClass@@AEAV1@@Z"(%class.FClass* dereferenceable(1) %arg) #0 !dbg !61 {
412entry:
413  %retval = alloca %class.FClass, align 1
414  %arg.addr = alloca %class.FClass*, align 8
415  store %class.FClass* %arg, %class.FClass** %arg.addr, align 8
416  call void @llvm.dbg.declare(metadata %class.FClass** %arg.addr, metadata !69, metadata !DIExpression()), !dbg !70
417  %0 = load %class.FClass*, %class.FClass** %arg.addr, align 8, !dbg !70
418  %coerce.dive = getelementptr inbounds %class.FClass, %class.FClass* %retval, i32 0, i32 0, !dbg !70
419  %1 = load i8, i8* %coerce.dive, align 1, !dbg !70
420  ret i8 %1, !dbg !70
421}
422
423; Function Attrs: noinline nounwind optnone uwtable
424define dso_local i8 @"?Func_AStruct@@YA?AUAStruct@@AEAU1@@Z"(%struct.AStruct* dereferenceable(1) %arg) #0 !dbg !71 {
425entry:
426  %retval = alloca %struct.AStruct, align 1
427  %arg.addr = alloca %struct.AStruct*, align 8
428  store %struct.AStruct* %arg, %struct.AStruct** %arg.addr, align 8
429  call void @llvm.dbg.declare(metadata %struct.AStruct** %arg.addr, metadata !76, metadata !DIExpression()), !dbg !77
430  %0 = load %struct.AStruct*, %struct.AStruct** %arg.addr, align 8, !dbg !77
431  %coerce.dive = getelementptr inbounds %struct.AStruct, %struct.AStruct* %retval, i32 0, i32 0, !dbg !77
432  %1 = load i8, i8* %coerce.dive, align 1, !dbg !77
433  ret i8 %1, !dbg !77
434}
435
436; Function Attrs: noinline nounwind optnone uwtable
437define dso_local void @"?Func_BStruct@@YA?AUBStruct@@AEAU1@@Z"(%struct.BStruct* noalias sret %agg.result, %struct.BStruct* dereferenceable(1) %arg) #0 !dbg !78 {
438entry:
439  %arg.addr = alloca %struct.BStruct*, align 8
440  store %struct.BStruct* %arg, %struct.BStruct** %arg.addr, align 8
441  call void @llvm.dbg.declare(metadata %struct.BStruct** %arg.addr, metadata !88, metadata !DIExpression()), !dbg !89
442  %0 = load %struct.BStruct*, %struct.BStruct** %arg.addr, align 8, !dbg !89
443  ret void, !dbg !89
444}
445
446; Function Attrs: noinline nounwind optnone uwtable
447define dso_local i8 @"?Func_AUnion@@YA?ATAUnion@@AEAT1@@Z"(%union.AUnion* dereferenceable(1) %arg) #0 !dbg !90 {
448entry:
449  %retval = alloca %union.AUnion, align 1
450  %arg.addr = alloca %union.AUnion*, align 8
451  store %union.AUnion* %arg, %union.AUnion** %arg.addr, align 8
452  call void @llvm.dbg.declare(metadata %union.AUnion** %arg.addr, metadata !95, metadata !DIExpression()), !dbg !96
453  %0 = load %union.AUnion*, %union.AUnion** %arg.addr, align 8, !dbg !96
454  %coerce.dive = getelementptr inbounds %union.AUnion, %union.AUnion* %retval, i32 0, i32 0, !dbg !96
455  %1 = load i8, i8* %coerce.dive, align 1, !dbg !96
456  ret i8 %1, !dbg !96
457}
458
459; Function Attrs: noinline nounwind optnone uwtable
460define dso_local void @"?Func_BUnion@@YA?ATBUnion@@AEAT1@@Z"(%union.BUnion* noalias sret %agg.result, %union.BUnion* dereferenceable(1) %arg) #0 !dbg !97 {
461entry:
462  %arg.addr = alloca %union.BUnion*, align 8
463  store %union.BUnion* %arg, %union.BUnion** %arg.addr, align 8
464  call void @llvm.dbg.declare(metadata %union.BUnion** %arg.addr, metadata !107, metadata !DIExpression()), !dbg !108
465  %0 = load %union.BUnion*, %union.BUnion** %arg.addr, align 8, !dbg !108
466  ret void, !dbg !108
467}
468
469attributes #0 = { noinline nounwind optnone uwtable "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+fxsr,+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" }
470attributes #1 = { nounwind readnone speculatable }
471
472!llvm.dbg.cu = !{!0}
473!llvm.module.flags = !{!3, !4, !5, !6}
474!llvm.ident = !{!7}
475
476!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !1, producer: "clang version 8.0.0", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, nameTableKind: None)
477!1 = !DIFile(filename: "function-options.cpp", directory: "\5Ctest\5CDebugInfo\5CCOFF", checksumkind: CSK_MD5, checksum: "e73e74ea0bd81174051f0a4746343e00")
478!2 = !{}
479!3 = !{i32 2, !"CodeView", i32 1}
480!4 = !{i32 2, !"Debug Info Version", i32 3}
481!5 = !{i32 1, !"wchar_size", i32 2}
482!6 = !{i32 7, !"PIC Level", i32 2}
483!7 = !{!"clang version 8.0.0"}
484!8 = distinct !DISubprogram(name: "Func_AClass", linkageName: "?Func_AClass@@YA?AVAClass@@AEAV1@@Z", scope: !9, file: !9, line: 6, type: !10, isLocal: false, isDefinition: true, scopeLine: 6, flags: DIFlagPrototyped, isOptimized: false, unit: !0, retainedNodes: !2)
485!9 = !DIFile(filename: "function-options.cpp", directory: "D:\5Cupstream\5Cllvm\5Ctest\5CDebugInfo\5CCOFF")
486!10 = !DISubroutineType(types: !11)
487!11 = !{!12, !13}
488!12 = distinct !DICompositeType(tag: DW_TAG_class_type, name: "AClass", file: !9, line: 5, size: 8, flags: DIFlagTypePassByValue | DIFlagTrivial, elements: !2, identifier: ".?AVAClass@@")
489!13 = !DIDerivedType(tag: DW_TAG_reference_type, baseType: !12, size: 64)
490!14 = !DILocalVariable(name: "arg", arg: 1, scope: !8, file: !9, line: 6, type: !13)
491!15 = !DILocation(line: 6, scope: !8)
492!16 = distinct !DISubprogram(name: "Func_BClass", linkageName: "?Func_BClass@@YA?AVBClass@@AEAV1@@Z", scope: !9, file: !9, line: 12, type: !17, isLocal: false, isDefinition: true, scopeLine: 12, flags: DIFlagPrototyped, isOptimized: false, unit: !0, retainedNodes: !2)
493!17 = !DISubroutineType(types: !18)
494!18 = !{!19, !25}
495!19 = distinct !DICompositeType(tag: DW_TAG_class_type, name: "BClass", file: !9, line: 8, size: 8, flags: DIFlagTypePassByValue | DIFlagNonTrivial, elements: !20, identifier: ".?AVBClass@@")
496!20 = !{!21}
497!21 = !DISubprogram(name: "BClass", scope: !19, file: !9, line: 10, type: !22, isLocal: false, isDefinition: false, scopeLine: 10, flags: DIFlagExplicit | DIFlagPrototyped, isOptimized: false)
498!22 = !DISubroutineType(types: !23)
499!23 = !{null, !24}
500!24 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !19, size: 64, flags: DIFlagArtificial | DIFlagObjectPointer)
501!25 = !DIDerivedType(tag: DW_TAG_reference_type, baseType: !19, size: 64)
502!26 = !DILocalVariable(name: "arg", arg: 1, scope: !16, file: !9, line: 12, type: !25)
503!27 = !DILocation(line: 12, scope: !16)
504!28 = distinct !DISubprogram(name: "Func_C1Class", linkageName: "?Func_C1Class@@YA?AVC1Class@@AEAV1@@Z", scope: !9, file: !9, line: 18, type: !29, isLocal: false, isDefinition: true, scopeLine: 18, flags: DIFlagPrototyped, isOptimized: false, unit: !0, retainedNodes: !2)
505!29 = !DISubroutineType(types: !30)
506!30 = !{!31, !37}
507!31 = distinct !DICompositeType(tag: DW_TAG_class_type, name: "C1Class", file: !9, line: 14, size: 8, flags: DIFlagTypePassByValue | DIFlagTrivial, elements: !32, identifier: ".?AVC1Class@@")
508!32 = !{!33}
509!33 = !DISubprogram(name: "C1Class", scope: !31, file: !9, line: 16, type: !34, isLocal: false, isDefinition: false, scopeLine: 16, flags: DIFlagPublic | DIFlagPrototyped, isOptimized: false)
510!34 = !DISubroutineType(types: !35)
511!35 = !{null, !36}
512!36 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !31, size: 64, flags: DIFlagArtificial | DIFlagObjectPointer)
513!37 = !DIDerivedType(tag: DW_TAG_reference_type, baseType: !31, size: 64)
514!38 = !DILocalVariable(name: "arg", arg: 1, scope: !28, file: !9, line: 18, type: !37)
515!39 = !DILocation(line: 18, scope: !28)
516!40 = distinct !DISubprogram(name: "Func_C2Class", linkageName: "?Func_C2Class@@YA?AVC2Class@@AEAV1@@Z", scope: !9, file: !9, line: 24, type: !41, isLocal: false, isDefinition: true, scopeLine: 24, flags: DIFlagPrototyped, isOptimized: false, unit: !0, retainedNodes: !2)
517!41 = !DISubroutineType(types: !42)
518!42 = !{!43, !49}
519!43 = distinct !DICompositeType(tag: DW_TAG_class_type, name: "C2Class", file: !9, line: 20, size: 8, flags: DIFlagTypePassByValue | DIFlagNonTrivial, elements: !44, identifier: ".?AVC2Class@@")
520!44 = !{!45}
521!45 = !DISubprogram(name: "~C2Class", scope: !43, file: !9, line: 22, type: !46, isLocal: false, isDefinition: false, scopeLine: 22, flags: DIFlagPublic | DIFlagPrototyped, isOptimized: false)
522!46 = !DISubroutineType(types: !47)
523!47 = !{null, !48}
524!48 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !43, size: 64, flags: DIFlagArtificial | DIFlagObjectPointer)
525!49 = !DIDerivedType(tag: DW_TAG_reference_type, baseType: !43, size: 64)
526!50 = !DILocalVariable(name: "arg", arg: 1, scope: !40, file: !9, line: 24, type: !49)
527!51 = !DILocation(line: 24, scope: !40)
528!52 = distinct !DISubprogram(name: "Func_DClass", linkageName: "?Func_DClass@@YA?AVDClass@@AEAV1@@Z", scope: !9, file: !9, line: 27, type: !53, isLocal: false, isDefinition: true, scopeLine: 27, flags: DIFlagPrototyped, isOptimized: false, unit: !0, retainedNodes: !2)
529!53 = !DISubroutineType(types: !54)
530!54 = !{!55, !58}
531!55 = distinct !DICompositeType(tag: DW_TAG_class_type, name: "DClass", file: !9, line: 26, size: 8, flags: DIFlagTypePassByValue | DIFlagNonTrivial, elements: !56, identifier: ".?AVDClass@@")
532!56 = !{!57}
533!57 = !DIDerivedType(tag: DW_TAG_inheritance, scope: !55, baseType: !19, flags: DIFlagPublic, extraData: i32 0)
534!58 = !DIDerivedType(tag: DW_TAG_reference_type, baseType: !55, size: 64)
535!59 = !DILocalVariable(name: "arg", arg: 1, scope: !52, file: !9, line: 27, type: !58)
536!60 = !DILocation(line: 27, scope: !52)
537!61 = distinct !DISubprogram(name: "Func_FClass", linkageName: "?Func_FClass@@YA?AVFClass@@AEAV1@@Z", scope: !9, file: !9, line: 30, type: !62, isLocal: false, isDefinition: true, scopeLine: 30, flags: DIFlagPrototyped, isOptimized: false, unit: !0, retainedNodes: !2)
538!62 = !DISubroutineType(types: !63)
539!63 = !{!64, !68}
540!64 = distinct !DICompositeType(tag: DW_TAG_class_type, name: "FClass", file: !9, line: 29, size: 8, flags: DIFlagTypePassByValue | DIFlagTrivial, elements: !65, identifier: ".?AVFClass@@")
541!65 = !{!66}
542!66 = !DIDerivedType(tag: DW_TAG_member, name: "x", scope: !64, file: !9, line: 29, baseType: !67, flags: DIFlagStaticMember)
543!67 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
544!68 = !DIDerivedType(tag: DW_TAG_reference_type, baseType: !64, size: 64)
545!69 = !DILocalVariable(name: "arg", arg: 1, scope: !61, file: !9, line: 30, type: !68)
546!70 = !DILocation(line: 30, scope: !61)
547!71 = distinct !DISubprogram(name: "Func_AStruct", linkageName: "?Func_AStruct@@YA?AUAStruct@@AEAU1@@Z", scope: !9, file: !9, line: 33, type: !72, isLocal: false, isDefinition: true, scopeLine: 33, flags: DIFlagPrototyped, isOptimized: false, unit: !0, retainedNodes: !2)
548!72 = !DISubroutineType(types: !73)
549!73 = !{!74, !75}
550!74 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "AStruct", file: !9, line: 32, size: 8, flags: DIFlagTypePassByValue | DIFlagTrivial, elements: !2, identifier: ".?AUAStruct@@")
551!75 = !DIDerivedType(tag: DW_TAG_reference_type, baseType: !74, size: 64)
552!76 = !DILocalVariable(name: "arg", arg: 1, scope: !71, file: !9, line: 33, type: !75)
553!77 = !DILocation(line: 33, scope: !71)
554!78 = distinct !DISubprogram(name: "Func_BStruct", linkageName: "?Func_BStruct@@YA?AUBStruct@@AEAU1@@Z", scope: !9, file: !9, line: 36, type: !79, isLocal: false, isDefinition: true, scopeLine: 36, flags: DIFlagPrototyped, isOptimized: false, unit: !0, retainedNodes: !2)
555!79 = !DISubroutineType(types: !80)
556!80 = !{!81, !87}
557!81 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "BStruct", file: !9, line: 35, size: 8, flags: DIFlagTypePassByValue | DIFlagNonTrivial, elements: !82, identifier: ".?AUBStruct@@")
558!82 = !{!83}
559!83 = !DISubprogram(name: "BStruct", scope: !81, file: !9, line: 35, type: !84, isLocal: false, isDefinition: false, scopeLine: 35, flags: DIFlagPrototyped, isOptimized: false)
560!84 = !DISubroutineType(types: !85)
561!85 = !{null, !86}
562!86 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !81, size: 64, flags: DIFlagArtificial | DIFlagObjectPointer)
563!87 = !DIDerivedType(tag: DW_TAG_reference_type, baseType: !81, size: 64)
564!88 = !DILocalVariable(name: "arg", arg: 1, scope: !78, file: !9, line: 36, type: !87)
565!89 = !DILocation(line: 36, scope: !78)
566!90 = distinct !DISubprogram(name: "Func_AUnion", linkageName: "?Func_AUnion@@YA?ATAUnion@@AEAT1@@Z", scope: !9, file: !9, line: 39, type: !91, isLocal: false, isDefinition: true, scopeLine: 39, flags: DIFlagPrototyped, isOptimized: false, unit: !0, retainedNodes: !2)
567!91 = !DISubroutineType(types: !92)
568!92 = !{!93, !94}
569!93 = distinct !DICompositeType(tag: DW_TAG_union_type, name: "AUnion", file: !9, line: 38, size: 8, flags: DIFlagTypePassByValue | DIFlagTrivial, elements: !2, identifier: ".?ATAUnion@@")
570!94 = !DIDerivedType(tag: DW_TAG_reference_type, baseType: !93, size: 64)
571!95 = !DILocalVariable(name: "arg", arg: 1, scope: !90, file: !9, line: 39, type: !94)
572!96 = !DILocation(line: 39, scope: !90)
573!97 = distinct !DISubprogram(name: "Func_BUnion", linkageName: "?Func_BUnion@@YA?ATBUnion@@AEAT1@@Z", scope: !9, file: !9, line: 42, type: !98, isLocal: false, isDefinition: true, scopeLine: 42, flags: DIFlagPrototyped, isOptimized: false, unit: !0, retainedNodes: !2)
574!98 = !DISubroutineType(types: !99)
575!99 = !{!100, !106}
576!100 = distinct !DICompositeType(tag: DW_TAG_union_type, name: "BUnion", file: !9, line: 41, size: 8, flags: DIFlagTypePassByValue | DIFlagTrivial, elements: !101, identifier: ".?ATBUnion@@")
577!101 = !{!102}
578!102 = !DISubprogram(name: "BUnion", scope: !100, file: !9, line: 41, type: !103, isLocal: false, isDefinition: false, scopeLine: 41, flags: DIFlagPrototyped, isOptimized: false)
579!103 = !DISubroutineType(types: !104)
580!104 = !{null, !105}
581!105 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !100, size: 64, flags: DIFlagArtificial | DIFlagObjectPointer)
582!106 = !DIDerivedType(tag: DW_TAG_reference_type, baseType: !100, size: 64)
583!107 = !DILocalVariable(name: "arg", arg: 1, scope: !97, file: !9, line: 42, type: !106)
584!108 = !DILocation(line: 42, scope: !97)
585