Manman Ren | 7b1e9b4 | 2013-08-28 18:31:02 +0000 | [diff] [blame] | 1 | // RUN: %clang -S -emit-llvm -target x86_64-unknown_unknown -g %s -o - -std=c++11 | FileCheck %s |
Devang Patel | fa275df | 2011-02-02 21:38:49 +0000 | [diff] [blame] | 2 | |
Stephen Hines | 0e2c34f | 2015-03-23 12:09:02 -0700 | [diff] [blame^] | 3 | // CHECK: !"0x11\00{{.*}}"{{, [^,]+, [^,]+}}, [[RETAIN:![0-9]*]], {{.*}} ; [ DW_TAG_compile_unit ] |
| 4 | // CHECK: [[EMPTY:![0-9]*]] = !{} |
| 5 | // CHECK: [[RETAIN]] = !{!{{[0-9]]*}}, [[FOO:![0-9]*]], |
David Blaikie | 776a364 | 2013-05-10 22:53:25 +0000 | [diff] [blame] | 6 | |
David Blaikie | 776a364 | 2013-05-10 22:53:25 +0000 | [diff] [blame] | 7 | |
Stephen Hines | 0e2c34f | 2015-03-23 12:09:02 -0700 | [diff] [blame^] | 8 | // CHECK: [[TC:![0-9]*]] = {{.*}}, [[TCARGS:![0-9]*]], !"{{.*}}"} ; [ DW_TAG_structure_type ] [TC<unsigned int, 2, &glb, &foo::e, &foo::f, &foo::g, 1, 2, 3>] |
| 9 | // CHECK: [[TCARGS]] = !{[[TCARG1:![0-9]*]], [[TCARG2:![0-9]*]], [[TCARG3:![0-9]*]], [[TCARG4:![0-9]*]], [[TCARG5:![0-9]*]], [[TCARG6:![0-9]*]], [[TCARG7:![0-9]*]]} |
David Blaikie | 0cd9ede | 2013-05-09 21:32:04 +0000 | [diff] [blame] | 10 | // |
| 11 | // We seem to be missing file/line/col info on template value parameters - |
David Blaikie | 9dfd243 | 2013-05-10 21:53:14 +0000 | [diff] [blame] | 12 | // metadata supports it but it's not populated. GCC doesn't emit it either, |
| 13 | // perhaps we should just drop it from the metadata. |
David Blaikie | 0cd9ede | 2013-05-09 21:32:04 +0000 | [diff] [blame] | 14 | // |
Stephen Hines | 0e2c34f | 2015-03-23 12:09:02 -0700 | [diff] [blame^] | 15 | // CHECK: [[TCARG1]] = !{!"0x2f\00T\000\000", null, [[UINT:![0-9]*]], null} ; [ DW_TAG_template_type_parameter ] |
David Blaikie | 9dfd243 | 2013-05-10 21:53:14 +0000 | [diff] [blame] | 16 | // CHECK: [[UINT:![0-9]*]] = {{.*}} ; [ DW_TAG_base_type ] [unsigned int] |
Stephen Hines | 0e2c34f | 2015-03-23 12:09:02 -0700 | [diff] [blame^] | 17 | // CHECK: [[TCARG2]] = !{!"0x30\00\00{{.*}}", {{[^,]+}}, [[UINT]], i32 2, {{.*}} ; [ DW_TAG_template_value_parameter ] |
| 18 | // CHECK: [[TCARG3]] = !{!"0x30\00x\00{{.*}}", {{[^,]+}}, [[CINTPTR:![0-9]*]], i32* @glb, {{.*}} ; [ DW_TAG_template_value_parameter ] |
| 19 | // CHECK: [[CINTPTR]] = {{.*}}, [[CINT:![0-9]*]]} ; [ DW_TAG_pointer_type ] {{.*}} [from ] |
| 20 | // CHECK: [[CINT]] = {{.*}}, [[INT:![0-9]*]]} ; [ DW_TAG_const_type ] {{.*}} [from int] |
Manman Ren | 83369bf | 2013-08-29 23:19:58 +0000 | [diff] [blame] | 21 | // CHECK: [[INT]] = {{.*}} ; [ DW_TAG_base_type ] [int] |
Stephen Hines | 0e2c34f | 2015-03-23 12:09:02 -0700 | [diff] [blame^] | 22 | // CHECK: [[TCARG4]] = !{!"0x30\00a\00{{.*}}", {{[^,]+}}, [[MEMINTPTR:![0-9]*]], i64 8, {{.*}} ; [ DW_TAG_template_value_parameter ] |
| 23 | // CHECK: [[MEMINTPTR]] = {{.*}}, !"_ZTS3foo"} ; [ DW_TAG_ptr_to_member_type ] {{.*}}[from int] |
David Blaikie | 9dfd243 | 2013-05-10 21:53:14 +0000 | [diff] [blame] | 24 | // |
| 25 | // Currently Clang emits the pointer-to-member-function value, but LLVM doesn't |
| 26 | // use it (GCC doesn't emit a value for pointers to member functions either - so |
| 27 | // it's not clear what, if any, format would be acceptable to GDB) |
| 28 | // |
Stephen Hines | 0e2c34f | 2015-03-23 12:09:02 -0700 | [diff] [blame^] | 29 | // CHECK: [[TCARG5]] = !{!"0x30\00b\00{{.*}}", {{[^,]+}}, [[MEMFUNPTR:![0-9]*]], { i64, i64 } { i64 ptrtoint (void (%struct.foo*)* @_ZN3foo1fEv to i64), i64 0 }, {{.*}} ; [ DW_TAG_template_value_parameter ] |
| 30 | // CHECK: [[MEMFUNPTR]] = {{.*}}, [[FTYPE:![0-9]*]], !"_ZTS3foo"} ; [ DW_TAG_ptr_to_member_type ] |
| 31 | // CHECK: [[FTYPE]] = {{.*}}, [[FARGS:![0-9]*]], null, null, null} ; [ DW_TAG_subroutine_type ] |
| 32 | // CHECK: [[FARGS]] = !{null, [[FARG1:![0-9]*]]} |
Manman Ren | 8e0f65f | 2013-10-05 01:43:22 +0000 | [diff] [blame] | 33 | // CHECK: [[FARG1]] = {{.*}} ; [ DW_TAG_pointer_type ] [line 0, size 64, align 64, offset 0] [artificial] [from _ZTS3foo] |
Manman Ren | 832e921 | 2013-09-05 18:51:02 +0000 | [diff] [blame] | 34 | // |
Stephen Hines | 0e2c34f | 2015-03-23 12:09:02 -0700 | [diff] [blame^] | 35 | // CHECK: [[TCARG6]] = !{!"0x30\00f\00{{.*}}", {{[^,]+}}, [[FUNPTR:![0-9]*]], void ()* @_ZN3foo1gEv, {{.*}} ; [ DW_TAG_template_value_parameter ] |
| 36 | // CHECK: [[FUNPTR]] = {{.*}}, [[FUNTYPE:![0-9]*]]} ; [ DW_TAG_pointer_type ] |
| 37 | // CHECK: [[FUNTYPE]] = {{.*}}, [[FUNARGS:![0-9]*]], null, null, null} ; [ DW_TAG_subroutine_type ] |
| 38 | // CHECK: [[FUNARGS]] = !{null} |
| 39 | // CHECK: [[TCARG7]] = !{!"0x4107\00Is\000\000", null, null, [[TCARG7_VALS:![0-9]*]], null} ; [ DW_TAG_GNU_template_parameter_pack ] |
| 40 | // CHECK: [[TCARG7_VALS]] = !{[[TCARG7_1:![0-9]*]], [[TCARG7_2:![0-9]*]], [[TCARG7_3:![0-9]*]]} |
| 41 | // CHECK: [[TCARG7_1]] = !{!"0x30\00\00{{.*}}", {{[^,]+}}, [[INT]], i32 1, {{.*}} ; [ DW_TAG_template_value_parameter ] |
| 42 | // CHECK: [[TCARG7_2]] = !{!"0x30\00\00{{.*}}", {{[^,]+}}, [[INT]], i32 2, {{.*}} ; [ DW_TAG_template_value_parameter ] |
| 43 | // CHECK: [[TCARG7_3]] = !{!"0x30\00\00{{.*}}", {{[^,]+}}, [[INT]], i32 3, {{.*}} ; [ DW_TAG_template_value_parameter ] |
Manman Ren | 8e0f65f | 2013-10-05 01:43:22 +0000 | [diff] [blame] | 44 | // |
| 45 | // We could just emit a declaration of 'foo' here, rather than the entire |
| 46 | // definition (same goes for any time we emit a member (function or data) |
| 47 | // pointer type) |
Stephen Hines | 0e2c34f | 2015-03-23 12:09:02 -0700 | [diff] [blame^] | 48 | // CHECK: [[FOO]] = {{.*}}, !"_ZTS3foo"} ; [ DW_TAG_structure_type ] [foo] |
| 49 | // CHECK: !"0x2e\00f\00f\00_ZN3foo1fEv\00{{.*}}", [[FTYPE:![0-9]*]], {{.*}} ; [ DW_TAG_subprogram ] |
Manman Ren | 8e0f65f | 2013-10-05 01:43:22 +0000 | [diff] [blame] | 50 | // |
Devang Patel | fa275df | 2011-02-02 21:38:49 +0000 | [diff] [blame] | 51 | |
Stephen Hines | 0e2c34f | 2015-03-23 12:09:02 -0700 | [diff] [blame^] | 52 | // CHECK: !"0x13\00{{.*}}", !{{[0-9]*}}, !"_ZTS2TCIjLj2EXadL_Z3glbEEXadL_ZN3foo1eEEEXadL_ZNS0_1fEvEEXadL_ZNS0_1gEvEEJLi1ELi2ELi3EEE", {{.*}}, !"[[TCNESTED:.*]]"} ; [ DW_TAG_structure_type ] [nested] |
| 53 | // CHECK: [[TCNARGS:![0-9]*]], !"[[TCNT:.*]]"} ; [ DW_TAG_structure_type ] [TC<int, -3, nullptr, nullptr, nullptr, nullptr>] |
| 54 | // CHECK: [[TCNARGS]] = !{[[TCNARG1:![0-9]*]], [[TCNARG2:![0-9]*]], [[TCNARG3:![0-9]*]], [[TCNARG4:![0-9]*]], [[TCNARG5:![0-9]*]], [[TCNARG6:![0-9]*]], [[TCNARG7:![0-9]*]]} |
| 55 | // CHECK: [[TCNARG1]] = !{!"0x2f\00T\000\000", null, [[INT]], null} ; [ DW_TAG_template_type_parameter ] |
| 56 | // CHECK: [[TCNARG2]] = !{!"0x30\00\000\000", null, [[INT]], i32 -3, null} ; [ DW_TAG_template_value_parameter ] |
| 57 | // CHECK: [[TCNARG3]] = !{!"0x30\00x\000\000", null, [[CINTPTR]], i8 0, null} ; [ DW_TAG_template_value_parameter ] |
David Blaikie | 9dfd243 | 2013-05-10 21:53:14 +0000 | [diff] [blame] | 58 | |
| 59 | // The interesting null pointer: -1 for member data pointers (since they are |
| 60 | // just an offset in an object, they can be zero and non-null for the first |
| 61 | // member) |
| 62 | |
Stephen Hines | 0e2c34f | 2015-03-23 12:09:02 -0700 | [diff] [blame^] | 63 | // CHECK: [[TCNARG4]] = !{!"0x30\00a\000\000", null, [[MEMINTPTR]], i64 -1, null} ; [ DW_TAG_template_value_parameter ] |
David Blaikie | 9dfd243 | 2013-05-10 21:53:14 +0000 | [diff] [blame] | 64 | // |
| 65 | // In some future iteration we could possibly emit the value of a null member |
| 66 | // function pointer as '{ i64, i64 } zeroinitializer' as it may be handled |
| 67 | // naturally from the LLVM CodeGen side once we decide how to handle non-null |
| 68 | // member function pointers. For now, it's simpler just to emit the 'i8 0'. |
| 69 | // |
Stephen Hines | 0e2c34f | 2015-03-23 12:09:02 -0700 | [diff] [blame^] | 70 | // CHECK: [[TCNARG5]] = !{!"0x30\00b\000\000", null, [[MEMFUNPTR]], i8 0, null} ; [ DW_TAG_template_value_parameter ] |
| 71 | // CHECK: [[TCNARG6]] = !{!"0x30\00f\000\000", null, [[FUNPTR]], i8 0, null} ; [ DW_TAG_template_value_parameter ] |
| 72 | // CHECK: [[TCNARG7]] = !{!"0x4107\00Is\000\000", null, null, [[EMPTY]], null} ; [ DW_TAG_GNU_template_parameter_pack ] |
Stephen Hines | 176edba | 2014-12-01 14:53:08 -0800 | [diff] [blame] | 73 | |
| 74 | // FIXME: these parameters should probably be rendered as 'glb' rather than |
| 75 | // '&glb', since they're references, not pointers. |
Stephen Hines | 0e2c34f | 2015-03-23 12:09:02 -0700 | [diff] [blame^] | 76 | // CHECK: [[NNARGS:![0-9]*]], !"[[NNT:.*]]"} ; [ DW_TAG_structure_type ] [NN<tmpl_impl, &glb, &glb>] |
| 77 | // CHECK: [[NNARGS]] = !{[[NNARG1:![0-9]*]], [[NNARG2:![0-9]*]], [[NNARG3:![0-9]*]]} |
| 78 | // CHECK: [[NNARG1]] = !{!"0x4106\00tmpl\000\000", null, null, !"tmpl_impl", null} ; [ DW_TAG_GNU_template_template_param ] |
| 79 | // CHECK: [[NNARG2]] = !{!"0x30\00lvr\00{{.*}}", {{[^,]+}}, [[INTLVR:![0-9]*]], i32* @glb, {{.*}} ; [ DW_TAG_template_value_parameter ] |
| 80 | // CHECK: [[INTLVR]] = {{.*}}, [[INT]]} ; [ DW_TAG_reference_type ] {{.*}} [from int] |
| 81 | // CHECK: [[NNARG3]] = !{!"0x30\00rvr\00{{.*}}", {{[^,]+}}, [[INTRVR:![0-9]*]], i32* @glb, {{.*}} ; [ DW_TAG_template_value_parameter ] |
| 82 | // CHECK: [[INTRVR]] = {{.*}}, [[INT]]} ; [ DW_TAG_rvalue_reference_type ] {{.*}} [from int] |
David Majnemer | 5db8b31 | 2013-08-25 22:13:27 +0000 | [diff] [blame] | 83 | |
Stephen Hines | 0e2c34f | 2015-03-23 12:09:02 -0700 | [diff] [blame^] | 84 | // CHECK: [[PTOARGS:![0-9]*]], !"{{.*}}"} ; [ DW_TAG_structure_type ] [PaddingAtEndTemplate<&PaddedObj>] |
| 85 | // CHECK: [[PTOARGS]] = !{[[PTOARG1:![0-9]*]]} |
| 86 | // CHECK: [[PTOARG1]] = !{!"0x30\00\000\000", null, [[CONST_PADDINGATEND_PTR:![0-9]*]], %struct.PaddingAtEnd* @PaddedObj, null} ; [ DW_TAG_template_value_parameter ] |
Manman Ren | 8e0f65f | 2013-10-05 01:43:22 +0000 | [diff] [blame] | 87 | // CHECK: [[CONST_PADDINGATEND_PTR]] = {{.*}} ; [ DW_TAG_pointer_type ] [line 0, size 64, align 64, offset 0] [from _ZTS12PaddingAtEnd] |
Manman Ren | 83369bf | 2013-08-29 23:19:58 +0000 | [diff] [blame] | 88 | |
Stephen Hines | 0e2c34f | 2015-03-23 12:09:02 -0700 | [diff] [blame^] | 89 | // CHECK: !"[[TCNESTED]]", %"struct.TC<unsigned int, 2, &glb, &foo::e, &foo::f, &foo::g, 1, 2, 3>::nested"* @tci, null} ; [ DW_TAG_variable ] [tci] |
Manman Ren | 83369bf | 2013-08-29 23:19:58 +0000 | [diff] [blame] | 90 | |
Stephen Hines | 0e2c34f | 2015-03-23 12:09:02 -0700 | [diff] [blame^] | 91 | // CHECK: !"[[TCNT]]", %struct.TC* @tcn, null} ; [ DW_TAG_variable ] [tcn] |
Stephen Hines | 176edba | 2014-12-01 14:53:08 -0800 | [diff] [blame] | 92 | |
Stephen Hines | 0e2c34f | 2015-03-23 12:09:02 -0700 | [diff] [blame^] | 93 | // CHECK: !"[[NNT]]", %struct.NN* @nn, null} ; [ DW_TAG_variable ] [nn] |
David Blaikie | f1e08ac | 2013-05-09 22:43:45 +0000 | [diff] [blame] | 94 | struct foo { |
David Blaikie | 9dfd243 | 2013-05-10 21:53:14 +0000 | [diff] [blame] | 95 | char pad[8]; // make the member pointer to 'e' a bit more interesting (nonzero) |
David Blaikie | f1e08ac | 2013-05-09 22:43:45 +0000 | [diff] [blame] | 96 | int e; |
| 97 | void f(); |
Stephen Hines | 176edba | 2014-12-01 14:53:08 -0800 | [diff] [blame] | 98 | static void g(); |
David Blaikie | f1e08ac | 2013-05-09 22:43:45 +0000 | [diff] [blame] | 99 | }; |
| 100 | |
Stephen Hines | 176edba | 2014-12-01 14:53:08 -0800 | [diff] [blame] | 101 | typedef int foo::*foo_mem; |
| 102 | |
| 103 | template<typename T, T, const int *x, foo_mem a, void (foo::*b)(), void (*f)(), int ...Is> |
David Blaikie | 8058833 | 2013-08-01 20:31:40 +0000 | [diff] [blame] | 104 | struct TC { |
| 105 | struct nested { |
| 106 | }; |
Devang Patel | 700a1cb | 2010-07-20 20:24:18 +0000 | [diff] [blame] | 107 | }; |
| 108 | |
David Blaikie | f1e08ac | 2013-05-09 22:43:45 +0000 | [diff] [blame] | 109 | int glb; |
David Blaikie | f8aa155 | 2013-05-13 06:57:50 +0000 | [diff] [blame] | 110 | void func(); |
David Blaikie | f1e08ac | 2013-05-09 22:43:45 +0000 | [diff] [blame] | 111 | |
Stephen Hines | 176edba | 2014-12-01 14:53:08 -0800 | [diff] [blame] | 112 | TC<unsigned, 2, &glb, &foo::e, &foo::f, &foo::g, 1, 2, 3>::nested tci; |
| 113 | TC<int, -3, nullptr, nullptr, nullptr, nullptr> tcn; |
| 114 | |
David Blaikie | 35178dc | 2013-06-22 18:59:18 +0000 | [diff] [blame] | 115 | template<typename> |
| 116 | struct tmpl_impl { |
| 117 | }; |
David Blaikie | 776a364 | 2013-05-10 22:53:25 +0000 | [diff] [blame] | 118 | |
Stephen Hines | 176edba | 2014-12-01 14:53:08 -0800 | [diff] [blame] | 119 | template <template <typename> class tmpl, int &lvr, int &&rvr> |
| 120 | struct NN { |
| 121 | }; |
| 122 | |
| 123 | NN<tmpl_impl, glb, glb> nn; |
David Majnemer | 87b1f6d | 2013-08-24 08:21:10 +0000 | [diff] [blame] | 124 | |
David Majnemer | 5db8b31 | 2013-08-25 22:13:27 +0000 | [diff] [blame] | 125 | struct PaddingAtEnd { |
| 126 | int i; |
| 127 | char c; |
| 128 | }; |
| 129 | |
| 130 | PaddingAtEnd PaddedObj = {}; |
| 131 | |
Stephen Hines | 176edba | 2014-12-01 14:53:08 -0800 | [diff] [blame] | 132 | template <PaddingAtEnd *> |
David Majnemer | 5db8b31 | 2013-08-25 22:13:27 +0000 | [diff] [blame] | 133 | struct PaddingAtEndTemplate { |
| 134 | }; |
| 135 | |
| 136 | PaddingAtEndTemplate<&PaddedObj> PaddedTemplateObj; |