175 lines · cpp
1// RUN: %clang_cc1 -std=c++98 -triple x86_64-linux-gnu -fenable-matrix -fclang-abi-compat=3.0 %s -emit-llvm -o - -Wno-c++11-extensions \2// RUN: | FileCheck --check-prefixes=CHECK,PRE39,PRE5,PRE12,PRE15 %s3// RUN: %clang_cc1 -std=c++17 -triple x86_64-linux-gnu -fenable-matrix -fclang-abi-compat=3.0 %s -emit-llvm -o - \4// RUN: | FileCheck --check-prefixes=CHECK,PRE39,PRE5,PRE12,PRE15 %s5// RUN: %clang_cc1 -std=c++17 -triple x86_64-linux-gnu -fenable-matrix -fclang-abi-compat=3.8 %s -emit-llvm -o - \6// RUN: | FileCheck --check-prefixes=CHECK,PRE39,PRE5,PRE12,PRE15 %s7// RUN: %clang_cc1 -std=c++17 -triple x86_64-linux-gnu -fenable-matrix -fclang-abi-compat=3.9 %s -emit-llvm -o - \8// RUN: | FileCheck --check-prefixes=CHECK,V39,PRE5,PRE12,PRE15 %s9// RUN: %clang_cc1 -std=c++17 -triple x86_64-linux-gnu -fenable-matrix -fclang-abi-compat=4.0 %s -emit-llvm -o - \10// RUN: | FileCheck --check-prefixes=CHECK,V39,PRE5,PRE12,PRE15 %s11// RUN: %clang_cc1 -std=c++17 -triple x86_64-linux-gnu -fenable-matrix -fclang-abi-compat=5 %s -emit-llvm -o - \12// RUN: | FileCheck --check-prefixes=CHECK,V39,V5,PRE12,PRE12-CXX17,PRE15 %s13// RUN: %clang_cc1 -std=c++17 -triple x86_64-linux-gnu -fenable-matrix -fclang-abi-compat=11 %s -emit-llvm -o - \14// RUN: | FileCheck --check-prefixes=CHECK,V39,V5,PRE12,PRE12-CXX17,PRE15 %s15// RUN: %clang_cc1 -std=c++20 -triple x86_64-linux-gnu -fenable-matrix -fclang-abi-compat=11 %s -emit-llvm -o - \16// RUN: | FileCheck --check-prefixes=CHECK,V39,V5,PRE12,PRE12-CXX17,PRE12-CXX20,PRE13-CXX20,PRE15 %s17// RUN: %clang_cc1 -std=c++20 -triple x86_64-linux-gnu -fenable-matrix -fclang-abi-compat=12 %s -emit-llvm -o - \18// RUN: | FileCheck --check-prefixes=CHECK,V39,V5,V12,V12-CXX17,V12-CXX20,PRE13-CXX20,PRE15 %s19// RUN: %clang_cc1 -std=c++20 -triple x86_64-linux-gnu -fenable-matrix -fclang-abi-compat=14 %s -emit-llvm -o - \20// RUN: | FileCheck --check-prefixes=CHECK,V39,V5,V12,V12-CXX17,V12-CXX20,V13-CXX20,PRE15 %s21// RUN: %clang_cc1 -std=c++98 -triple x86_64-linux-gnu -fenable-matrix -fclang-abi-compat=latest %s -emit-llvm -o - -Wno-c++11-extensions \22// RUN: | FileCheck --check-prefixes=CHECK,V39,V5,V12,V15 %s23// RUN: %clang_cc1 -std=c++20 -triple x86_64-linux-gnu -fenable-matrix -fclang-abi-compat=latest %s -emit-llvm -o - \24// RUN: | FileCheck --check-prefixes=CHECK,V39,V5,V12,V12-CXX17,V12-CXX20,V13-CXX20,V15 %s25 26typedef __attribute__((vector_size(8))) long long v1xi64;27void clang39(v1xi64) {}28// PRE39: @_Z7clang39Dv1_x(i6429// V39: @_Z7clang39Dv1_x(double30 31struct A {32 A(const A&) = default;33 A(A&&);34};35void clang5(A) {}36// PRE5: @_Z6clang51A()37// V5: @_Z6clang51A(ptr38 39namespace mangle_template_prefix {40 // PRE12: @_ZN22mangle_template_prefix1fINS_1TEEEvNT_1UIiE1VIiEENS4_S5_IfEE(41 // V12: @_ZN22mangle_template_prefix1fINS_1TEEEvNT_1UIiE1VIiEENS5_IfEE(42 template<typename T> void f(typename T::template U<int>::template V<int>, typename T::template U<int>::template V<float>);43 struct T { template<typename I> struct U { template<typename J> using V = int; }; };44 void g() { f<T>(1, 2); }45}46 47int arg;48template<const int *> struct clang12_unchanged {};49// CHECK: @_Z4test17clang12_unchangedIXadL_Z3argEEE50void test(clang12_unchanged<&arg>) {}51 52#if __cplusplus >= 201703L53// PRE12-CXX17: @_Z4test15clang12_changedIXadL_Z3argEEE54// V12-CXX17: @_Z4test15clang12_changedIXcvPKiadL_Z3argEEE55template<auto> struct clang12_changed {};56void test(clang12_changed<(const int*)&arg>) {}57#endif58 59// PRE12: @_Z9clang12_aIXadL_Z3argEEEvv60// V12: @_Z9clang12_aIXcvPKiadL_Z3argEEEvv61template<const int *> void clang12_a() {}62template void clang12_a<&arg>();63 64// PRE12: @_Z9clang12_bIXadL_Z3arrEEEvv65// V12: @_Z9clang12_bIXadsoKcL_Z3arrEEEEvv66extern const char arr[6] = "hello";67template<const char *> void clang12_b() {}68template void clang12_b<arr>();69 70// CHECK: @_Z9clang12_cIXadL_Z3arrEEEvv71template<const char (*)[6]> void clang12_c() {}72template void clang12_c<&arr>();73 74 75/// Tests for <template-arg> <expr-primary> changes in clang12:76namespace expr_primary {77struct A {78 template<int N> struct Int {};79 template<int& N> struct Ref {};80};81 82/// Check various DeclRefExpr manglings83 84// PRE12: @_ZN12expr_primary5test1INS_1AEEEvNT_3IntIXLi1EEEE85// V12: @_ZN12expr_primary5test1INS_1AEEEvNT_3IntILi1EEE86template <typename T> void test1(typename T::template Int<1> a) {}87template void test1<A>(typename A::template Int<1> a);88 89enum Enum { EnumVal = 4 };90int Global;91 92// PRE12: @_ZN12expr_primary5test2INS_1AEEEvNT_3IntIXLNS_4EnumE4EEEE93// V12: @_ZN12expr_primary5test2INS_1AEEEvNT_3IntILNS_4EnumE4EEE94template <typename T> void test2(typename T::template Int<EnumVal> a) {}95template void test2<A>(typename A::template Int<4> a);96 97// CHECK: @_ZN12expr_primary5test3ILi3EEEvNS_1A3IntIXT_EEE98template <int X> void test3(typename A::template Int<X> a) {}99template void test3<3>(A::Int<3> a);100 101#if __cplusplus >= 202002L102// CHECK-CXX20: @_ZN12expr_primary5test4INS_1AEEEvNT_3RefIL_ZNS_6GlobalEEEE103template <typename T> void test4(typename T::template Ref<(Global)> a) {}104template void test4<A>(typename A::template Ref<Global> a);105 106struct B {107 struct X {108 constexpr X(double) {}109 constexpr X(int&) {}110 };111 template<X> struct Y {};112};113 114// PRE12-CXX20: _ZN12expr_primary5test5INS_1BEEEvNT_1YIXLd3ff0000000000000EEEE115// V12-CXX20: _ZN12expr_primary5test5INS_1BEEEvNT_1YILd3ff0000000000000EEE116template<typename T> void test5(typename T::template Y<1.0>) { }117template void test5<B>(typename B::Y<1.0>);118 119// PRE12-CXX20: @_ZN12expr_primary5test6INS_1BEEENT_1YIL_ZZNS_5test6EiE1bEEEi120// V12-CXX20: @_ZN12expr_primary5test6INS_1BEEENT_1YIXfp_EEEi121template<typename T> auto test6(int b) -> typename T::template Y<b> { return {}; }122template auto test6<B>(int b) -> B::Y<b>;123#endif124 125/// Verify non-dependent type-traits within a dependent template arg.126 127// PRE12: @_ZN12expr_primary5test7INS_1AEEEvNT_3IntIXLm1EEEE128// V12: @_ZN12expr_primary5test7INS_1AEEEvNT_3IntILm1EEE129template <class T> void test7(typename T::template Int<sizeof(char)> a) {}130template void test7<A>(A::Int<1>);131 132// PRE12: @_ZN12expr_primary5test8ILi2EEEvu11matrix_typeIXLi1EEXT_EiE133// V12: @_ZN12expr_primary5test8ILi2EEEvu11matrix_typeILi1EXT_EiE134template<int N> using matrix1xN = int __attribute__((matrix_type(1, N)));135template<int N> void test8(matrix1xN<N> a) {}136template void test8<2>(matrix1xN<2> a);137 138// PRE12: @_ZN12expr_primary5test9EUa9enable_ifIXLi1EEEv139// V12: @_ZN12expr_primary5test9EUa9enable_ifILi1EEv140void test9(void) __attribute__((enable_if(1, ""))) {}141 142}143 144#if __cplusplus >= 202002L145// PRE13-CXX20: @_Z15observe_lambdasI17inline_var_lambdaMUlvE_17inline_var_lambdaMUlvE0_PiS2_S0_S1_EiT_T0_T1_T2_146// V13-CXX20: @_Z15observe_lambdasIN17inline_var_lambdaMUlvE_ENS0_UlvE0_EPiS3_S1_S2_EiT_T0_T1_T2_147template <typename T, typename U, typename V, typename W, typename = T, typename = U>148int observe_lambdas(T, U, V, W) { return 0; }149inline auto inline_var_lambda = observe_lambdas([]{}, []{}, (int*)0, (int*)0);150int use_inline_var_lambda() { return inline_var_lambda; }151#endif152 153struct X {154 struct Y {155 using a = int;156 using b = int;157 };158};159template <typename T> void test10(typename T::Y::a, typename T::Y::b, float*, float*) {}160// PRE15: @_Z6test10I1XEvNT_1Y1aENS1_1Y1bEPfS4_161// V15: @_Z6test10I1XEvNT_1Y1aENS2_1bEPfS5_162template void test10<X>(int, int, float*, float*);163 164namespace test_substitution {165struct S { int f(void *, void *); };166 167typedef int (S::*s_func)(void *, void *);168 169// clang used to incorrectly emit 'S0_' for the second 'void *' parameter type170// when targeting older ABIs because of a bug in the mangler.171 172// CHECK-LABEL: define dso_local void @_ZN17test_substitution4foo1EMNS_1SEFiPvS1_E(173void foo1(s_func s) {}174}175