Eric Fiselier | b42c73d | 2019-05-16 21:51:39 +0000 | [diff] [blame^] | 1 | // RUN: %clang_cc1 -std=c++2a -fblocks %s -triple x86_64-unknown-unknown -emit-llvm -o %t.ll |
Eric Fiselier | 708afb5 | 2019-05-16 21:04:15 +0000 | [diff] [blame] | 2 | |
| 3 | #line 8 "builtin-source-location.cpp" |
| 4 | |
| 5 | struct source_location { |
| 6 | private: |
| 7 | unsigned int __m_line = 0; |
| 8 | unsigned int __m_col = 0; |
| 9 | const char *__m_file = nullptr; |
| 10 | const char *__m_func = nullptr; |
| 11 | |
| 12 | public: |
| 13 | constexpr void set(unsigned l, unsigned c, const char *f, const char *func) { |
| 14 | __m_line = l; |
| 15 | __m_col = c; |
| 16 | __m_file = f; |
| 17 | __m_func = func; |
| 18 | } |
| 19 | static constexpr source_location current( |
| 20 | unsigned int __line = __builtin_LINE(), |
| 21 | unsigned int __col = __builtin_COLUMN(), |
| 22 | const char *__file = __builtin_FILE(), |
| 23 | const char *__func = __builtin_FUNCTION()) noexcept { |
| 24 | source_location __loc; |
| 25 | __loc.set(__line, __col, __file, __func); |
| 26 | return __loc; |
| 27 | } |
| 28 | static source_location bad_current( |
| 29 | unsigned int __line = __builtin_LINE(), |
| 30 | unsigned int __col = __builtin_COLUMN(), |
| 31 | const char *__file = __builtin_FILE(), |
| 32 | const char *__func = __builtin_FUNCTION()) noexcept { |
| 33 | source_location __loc; |
| 34 | __loc.set(__line, __col, __file, __func); |
| 35 | return __loc; |
| 36 | } |
| 37 | constexpr source_location() = default; |
| 38 | constexpr source_location(source_location const &) = default; |
| 39 | constexpr unsigned int line() const noexcept { return __m_line; } |
| 40 | constexpr unsigned int column() const noexcept { return __m_col; } |
| 41 | constexpr const char *file() const noexcept { return __m_file; } |
| 42 | constexpr const char *function() const noexcept { return __m_func; } |
| 43 | }; |
| 44 | |
| 45 | using SL = source_location; |
| 46 | |
| 47 | extern "C" int sink(...); |
| 48 | |
| 49 | |
| 50 | // RUN: FileCheck --input-file %t.ll %s --check-prefix=CHECK-GLOBAL-ONE |
| 51 | // |
| 52 | // CHECK-GLOBAL-ONE-DAG: @[[FILE:.*]] = {{.*}}c"test_const_init.cpp\00" |
| 53 | // CHECK-GLOBAL-ONE-DAG: @[[FUNC:.*]] = private unnamed_addr constant [1 x i8] zeroinitializer, align 1 |
| 54 | // |
| 55 | // CHECK-GLOBAL-ONE: @const_init_global = global %struct.source_location { i32 1000, i32 {{[0-9]+}}, {{[^@]*}}@[[FILE]], {{[^@]*}}@[[FUNC]] |
| 56 | #line 1000 "test_const_init.cpp" |
| 57 | SL const_init_global = SL::current(); |
| 58 | |
| 59 | // RUN: FileCheck --input-file %t.ll %s --check-prefix=CHECK-GLOBAL-TWO |
| 60 | // |
| 61 | // CHECK-GLOBAL-TWO-DAG: @runtime_init_global = global %struct.source_location zeroinitializer, align 8 |
| 62 | // |
| 63 | // CHECK-GLOBAL-TWO-DAG: @[[FILE:.*]] = {{.*}}c"test_runtime_init.cpp\00" |
| 64 | // CHECK-GLOBAL-TWO-DAG: @[[FUNC:.*]] = private unnamed_addr constant [1 x i8] zeroinitializer, align 1 |
| 65 | // |
| 66 | // CHECK-GLOBAL-TWO: define internal void @__cxx_global_var_init() |
| 67 | // CHECK-GLOBAL-TWO-NOT: ret |
| 68 | // CHECK-GLOBAL-TWO: call void @_ZN15source_location11bad_currentEjjPKcS1_(%struct.source_location* sret @runtime_init_global, |
| 69 | // CHECK-GLOBAL-TWO-SAME: i32 1100, i32 {{[0-9]+}}, {{[^@]*}}@[[FILE]], {{[^@]*}}@[[FUNC]], |
| 70 | #line 1100 "test_runtime_init.cpp" |
| 71 | SL runtime_init_global = SL::bad_current(); |
| 72 | |
| 73 | #line 2000 "test_function.cpp" |
| 74 | extern "C" void test_function() { |
| 75 | // RUN: FileCheck --input-file %t.ll %s --check-prefix=CHECK-LOCAL-ONE |
| 76 | // |
| 77 | // CHECK-LOCAL-ONE-DAG: @[[FILE:.*]] = {{.*}}c"test_current.cpp\00" |
| 78 | // CHECK-LOCAL-ONE-DAG: @[[FUNC:.*]] = {{.*}}c"test_function\00" |
| 79 | // |
| 80 | // CHECK-LOCAL-ONE: call void @_ZN15source_location7currentEjjPKcS1_(%struct.source_location* sret %local, |
| 81 | // CHECK-LOCAL-ONE-SAME: i32 2100, i32 {{[0-9]+}}, |
| 82 | // CHECK-LOCAL-ONE-SAME: {{[^@]*}}@[[FILE]], {{[^@]*}}@[[FUNC]], |
| 83 | #line 2100 "test_current.cpp" |
| 84 | SL local = SL::current(); |
| 85 | } |
| 86 | |
| 87 | #line 3000 "TestInitClass.cpp" |
| 88 | struct TestInit { |
| 89 | SL info = SL::current(); |
| 90 | SL arg_info; |
| 91 | |
| 92 | #line 3100 "TestInitCtor.cpp" |
| 93 | TestInit(SL arg_info = SL::current()) : arg_info(arg_info) {} |
| 94 | }; |
| 95 | |
| 96 | // RUN: FileCheck --input-file %t.ll %s --check-prefix=CHECK-CTOR-GLOBAL |
| 97 | // |
| 98 | // CHECK-CTOR-GLOBAL-DAG: @GlobalInitVal = global %struct.TestInit zeroinitializer, align 8 |
| 99 | // CHECK-CTOR-GLOBAL-DAG: @[[FILE:.*]] = {{.*}}c"GlobalInitVal.cpp\00" |
| 100 | // CHECK-CTOR-GLOBAL-DAG: @[[FUNC:.*]] = private unnamed_addr constant [1 x i8] zeroinitializer, align 1 |
| 101 | // |
| 102 | // CHECK-CTOR-GLOBAL: define internal void @__cxx_global_var_init.{{[0-9]+}}() |
| 103 | // CHECK-CTOR-GLOBAL-NOT: ret |
| 104 | // |
| 105 | // CHECK-CTOR-GLOBAL: call void @_ZN15source_location7currentEjjPKcS1_(%struct.source_location* sret %[[TMP_ONE:[^,]*]], |
| 106 | // CHECK-CTOR-GLOBAL-SAME: i32 3400, i32 {{[0-9]+}}, {{[^@]*}}@[[FILE]], {{[^@]*}}@[[FUNC]], |
| 107 | // CHECK-CTOR-GLOBAL-NEXT: call void @_ZN8TestInitC1E15source_location(%struct.TestInit* @GlobalInitVal, %struct.source_location* {{[^%]*}}%[[TMP_ONE]]) |
| 108 | #line 3400 "GlobalInitVal.cpp" |
| 109 | TestInit GlobalInitVal; |
| 110 | |
| 111 | extern "C" void test_init_function() { |
| 112 | // RUN: FileCheck --input-file %t.ll %s --check-prefix=CHECK-CTOR-LOCAL |
| 113 | // |
| 114 | // CHECK-CTOR-LOCAL-DAG: @[[FILE:.*]] = {{.*}}c"LocalInitVal.cpp\00" |
| 115 | // CHECK-CTOR-LOCAL-DAG: @[[FUNC:.*]] = {{.*}}c"test_init_function\00" |
| 116 | // |
| 117 | // CHECK-CTOR-LOCAL: define void @test_init_function() |
| 118 | // CHECK-CTOR-LOCAL-NOT: ret |
| 119 | // |
| 120 | // CHECK-CTOR-LOCAL: call void @_ZN15source_location7currentEjjPKcS1_(%struct.source_location* sret %[[TMP:[^,]*]], |
| 121 | // CHECK-CTOR-LOCAL-SAME: i32 3500, i32 {{[0-9]+}}, {{[^@]*}}@[[FILE]], {{[^@]*}}@[[FUNC]], |
| 122 | // CHECK-CTOR-LOCAL-NEXT: call void @_ZN8TestInitC1E15source_location(%struct.TestInit* %init_local, %struct.source_location* {{[^%]*}}%[[TMP]]) |
| 123 | #line 3500 "LocalInitVal.cpp" |
| 124 | TestInit init_local; |
| 125 | sink(init_local); |
| 126 | } |
| 127 | |
| 128 | #line 4000 "ConstexprClass.cpp" |
| 129 | struct TestInitConstexpr { |
| 130 | SL info = SL::current(); |
| 131 | SL arg_info; |
| 132 | #line 4200 "ConstexprCtor.cpp" |
| 133 | constexpr TestInitConstexpr(SL arg_info = SL::current()) : arg_info(arg_info) {} |
| 134 | }; |
| 135 | |
| 136 | // RUN: FileCheck --input-file %t.ll %s --check-prefix=CHECK-CONSTEXPR-T2 |
| 137 | // |
| 138 | // CHECK-CONSTEXPR-T2-DAG: @[[FILE_INIT:.*]] = {{.*}}c"ConstexprCtor.cpp\00" |
| 139 | // CHECK-CONSTEXPR-T2-DAG: @[[FUNC_INIT:.*]] = {{.*}}c"TestInitConstexpr\00" |
| 140 | // CHECK-CONSTEXPR-T2-DAG: @[[FILE_ARG:.*]] = {{.*}}c"ConstexprGlobal.cpp\00" |
| 141 | // CHECK-CONSTEXPR-T2-DAG: @[[EMPTY:.*]] = private unnamed_addr constant [1 x i8] zeroinitializer, align 1 |
| 142 | // |
| 143 | // CHECK-CONSTEXPR-T2: @ConstexprGlobal = global %struct.TestInitConstexpr { |
| 144 | // CHECK-CONSTEXPR-T2-SAME: %struct.source_location { i32 4200, i32 {{[0-9]+}}, {{[^@]*}}@[[FILE_INIT]], {{[^@]*}}@[[FUNC_INIT]], |
| 145 | // CHECK-CONSTEXPR-T2-SAME: {{[^%]*}}%struct.source_location { i32 4400, i32 {{[0-9]+}}, {{[^@]*}}@[[FILE_ARG]], {{[^@]*}}@[[EMPTY]] |
| 146 | #line 4400 "ConstexprGlobal.cpp" |
| 147 | TestInitConstexpr ConstexprGlobal; |
| 148 | |
| 149 | extern "C" void test_init_function_constexpr() { |
| 150 | // RUN: FileCheck --input-file %t.ll %s --check-prefix=CHECK-CONSTEXPR-LOCAL |
| 151 | // |
| 152 | // CHECK-CONSTEXPR-LOCAL-DAG: @[[FUNC:.*]] = {{.*}}c"test_init_function_constexpr\00" |
| 153 | // CHECK-CONSTEXPR-LOCAL-DAG: @[[FILE:.*]] = {{.*}}c"ConstexprLocal.cpp\00" |
| 154 | // |
| 155 | // CHECK-CONSTEXPR-LOCAL: define void @test_init_function_constexpr() |
| 156 | // CHECK-CONSTEXPR-LOCAL: call void @_ZN15source_location7currentEjjPKcS1_(%struct.source_location* sret %[[TMP:[^,]*]], |
| 157 | // CHECK-CONSTEXPR-LOCAL-SAME: i32 4600, i32 {{[0-9]+}}, {{[^@]*}}@[[FILE]], {{[^@]*}}@[[FUNC]] |
| 158 | // CHECK-CONSTEXPR-LOCAL: call void @_ZN17TestInitConstexprC1E15source_location(%struct.TestInitConstexpr* %local_val, {{.*}}%[[TMP]]) |
| 159 | #line 4600 "ConstexprLocal.cpp" |
| 160 | TestInitConstexpr local_val; |
| 161 | } |
| 162 | |
| 163 | #line 5000 "TestInitAgg.cpp" |
| 164 | struct TestInitAgg { |
| 165 | #line 5100 "i1.cpp" |
| 166 | SL i1; |
| 167 | #line 5200 "i2.cpp" |
| 168 | SL i2 = SL::current(); |
| 169 | #line 5300 "TestInitAggEnd.cpp" |
| 170 | }; |
| 171 | |
| 172 | // RUN: FileCheck --input-file %t.ll %s --check-prefix=CHECK-AGG-DEFAULT |
| 173 | // |
| 174 | // CHECK-AGG-DEFAULT-DAG: @[[FILE:.*]] = {{.*}}c"TestInitAgg.cpp\00" |
| 175 | // CHECK-AGG-DEFAULT-DAG: @[[FUNC:.*]] = {{.*}}c"TestInitAgg\00" |
| 176 | // |
| 177 | // CHECK-AGG-DEFAULT: @GlobalAggDefault = global %struct.TestInitAgg { |
| 178 | // CHECK-AGG-DEFAULT-SAME: %struct.source_location zeroinitializer, |
| 179 | // CHECK-AGG-DEFAULT-SAME: %struct.source_location { i32 5000, i32 {{[0-9]+}}, {{[^@]*}}@[[FILE]], {{[^@]*}}@[[FUNC]] |
| 180 | #line 5400 "GlobalAggDefault.cpp" |
| 181 | TestInitAgg GlobalAggDefault; |
| 182 | |
| 183 | #line 5500 "test_agg_init_test.cpp" |
| 184 | extern "C" void test_agg_init() { |
| 185 | // RUN: FileCheck --input-file %t.ll %s --check-prefix=CHECK-AGG-BRACE |
| 186 | // |
| 187 | // CHECK-AGG-BRACE-DAG: @[[FILE:.*]] = {{.*}}c"BraceInitEnd.cpp\00" |
| 188 | // CHECK-AGG-BRACE-DAG: @[[FUNC:.*]] = {{.*}}c"test_agg_init\00" |
| 189 | // |
| 190 | // CHECK-AGG-BRACE: define void @test_agg_init() |
| 191 | // CHECK-AGG-BRACE: %[[I2:.*]] = getelementptr inbounds %struct.TestInitAgg, %struct.TestInitAgg* %local_brace_init, i32 0, i32 1 |
| 192 | // CHECK-AGG-BRACE-NEXT: call void @_ZN15source_location7currentEjjPKcS1_(%struct.source_location* sret %[[I2]], |
| 193 | // CHECK-AGG-BRACE-SAME: i32 5700, i32 {{[0-9]+}}, {{[^@]*}}@[[FILE]], {{[^@]*}}@[[FUNC]] |
| 194 | #line 5600 "BraceInitStart.cpp" |
| 195 | TestInitAgg local_brace_init{ |
| 196 | #line 5700 "BraceInitEnd.cpp" |
| 197 | }; |
| 198 | |
| 199 | // RUN: FileCheck --input-file %t.ll %s --check-prefix=CHECK-AGG-EQUAL |
| 200 | // |
| 201 | // CHECK-AGG-EQUAL-DAG: @[[FILE:.*]] = {{.*}}c"EqualInitEnd.cpp\00" |
| 202 | // CHECK-AGG-EQUAL-DAG: @[[FUNC:.*]] = {{.*}}c"test_agg_init\00" |
| 203 | // |
| 204 | // CHECK-AGG-EQUAL: define void @test_agg_init() |
| 205 | // CHECK-AGG-EQUAL: %[[I2:.*]] = getelementptr inbounds %struct.TestInitAgg, %struct.TestInitAgg* %local_equal_init, i32 0, i32 1 |
| 206 | // CHECK-AGG-EQUAL-NEXT: call void @_ZN15source_location7currentEjjPKcS1_(%struct.source_location* sret %[[I2]], |
| 207 | // CHECK-AGG-EQUAL-SAME: i32 5900, i32 {{[0-9]+}}, {{[^@]*}}@[[FILE]], {{[^@]*}}@[[FUNC]] |
| 208 | #line 5800 "EqualInitStart.cpp" |
| 209 | TestInitAgg local_equal_init = |
| 210 | { |
| 211 | #line 5900 "EqualInitEnd.cpp" |
| 212 | }; |
| 213 | |
| 214 | // RUN: FileCheck --input-file %t.ll %s --check-prefix=CHECK-AGG-LIST |
| 215 | // |
| 216 | // CHECK-AGG-LIST-DAG: @[[FILE_DEFAULT:.*]] = {{.*}}c"InitListEnd.cpp\00" |
| 217 | // CHECK-AGG-LIST-DAG: @[[FILE_ELEM:.*]] = {{.*}}c"ListElem.cpp\00" |
| 218 | // CHECK-AGG-LIST-DAG: @[[FUNC:.*]] = {{.*}}c"test_agg_init\00" |
| 219 | // |
| 220 | // CHECK-AGG-LIST: define void @test_agg_init() |
| 221 | // |
| 222 | // CHECK-AGG-LIST: %[[I1:.*]] = getelementptr inbounds %struct.TestInitAgg, %struct.TestInitAgg* %local_list_init, i32 0, i32 0 |
| 223 | // CHECK-AGG-LIST-NEXT: call void @_ZN15source_location7currentEjjPKcS1_(%struct.source_location* sret %[[I1]], |
| 224 | // CHECK-AGG-LIST-SAME: i32 6100, i32 {{[0-9]+}}, {{[^@]*}}@[[FILE_ELEM]], {{[^@]*}}@[[FUNC]] |
| 225 | // |
| 226 | // CHECK-AGG-LIST: %[[I2:.*]] = getelementptr inbounds %struct.TestInitAgg, %struct.TestInitAgg* %local_list_init, i32 0, i32 1 |
| 227 | // CHECK-AGG-LIST-NEXT: call void @_ZN15source_location7currentEjjPKcS1_(%struct.source_location* sret %[[I2]], |
| 228 | // CHECK-AGG-LIST-SAME: i32 6200, i32 {{[0-9]+}}, {{[^@]*}}@[[FILE_DEFAULT]], {{[^@]*}}@[[FUNC]] |
| 229 | #line 6000 "InitListStart.cpp" |
| 230 | TestInitAgg local_list_init = |
| 231 | { |
| 232 | #line 6100 "ListElem.cpp" |
| 233 | {SL::current()} |
| 234 | #line 6200 "InitListEnd.cpp" |
| 235 | }; |
| 236 | } |
| 237 | |
| 238 | #line 7000 "TestTemplate.cpp" |
| 239 | template <class Tp, int> |
| 240 | struct TestTemplate { |
| 241 | Tp info = Tp::current(); |
| 242 | Tp arg_info; |
| 243 | #line 7100 "TestTemplateCtor.cpp" |
| 244 | constexpr TestTemplate(Tp arg_info = Tp::current()) : arg_info(arg_info) {} |
| 245 | }; |
| 246 | |
| 247 | #line 7200 "test_template.cpp" |
| 248 | template <class T, int V> |
| 249 | void test_template() { |
| 250 | |
| 251 | // RUN: FileCheck --input-file %t.ll %s --check-prefix=CHECK-TEMPL -DINT_ID=0 |
| 252 | // RUN: FileCheck --input-file %t.ll %s --check-prefix=CHECK-TEMPL -DINT_ID=1 |
| 253 | // |
| 254 | // CHECK-TEMPL-DAG: @[[FILE:.*]] = {{.*}}c"local_templ.cpp\00" |
| 255 | // CHECK-TEMPL-DAG: @[[FUNC:.*]] = {{.*}}c"test_template\00" |
| 256 | // |
| 257 | // CHECK-TEMPL: define weak_odr void @_Z13test_templateI15source_locationLi[[INT_ID]]EEvv() |
| 258 | // CHECK-TEMPL-NEXT: entry: |
| 259 | // CHECK-TEMPL-NOT: ret |
| 260 | // |
| 261 | // CHECK-TEMPL: call void @_ZN15source_location7currentEjjPKcS1_(%struct.source_location* sret %[[TMP:[^,]*]], |
| 262 | // CHECK-TEMPL-SAME: i32 7300, i32 {{[0-9]+}}, {{[^@]*}}@[[FILE]], {{[^@]*}}@[[FUNC]] |
| 263 | #line 7300 "local_templ.cpp" |
| 264 | TestTemplate<T, V> local_templ; |
| 265 | } |
| 266 | #line 7400 "EndTestTemplate.cpp" |
| 267 | template void test_template<SL, 0>(); |
| 268 | template void test_template<SL, 1>(); |