blob: 8ba3bc1df959e9aa1760f28450c5df1386d4bcbc [file] [log] [blame]
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
// RUN: cxx_compiler cxx_11 -c %s -o %t.o
// RUN: bindump %t.o | FileCheck prefixes %s
#include <cstddef>
// CHECK-DAG: _Z3f24Dn
void f24(std::nullptr_t) {}
// decltype
// CHECK-DAG: _Z3f25ILi3EEvDtT_E
template <int I> void f25(decltype(I));
template<> void f25<3>(int) {}
// CHECK-DAG: _Z1FIiEDTcl1gfp_EET_
void g(int);
template <class T> auto F(T p)->decltype(g(p));
// return type in the mangling of the template signature is encoded as DTcl1gfp_E
template <> auto F(int p)->decltype(g(p)) {}
// CHECK-DAG: _Z1fN1SUt_E
struct S { static struct {} x; };
typedef decltype(S::x) TX;
void f(TX) {}
// CHECK-DAG: _ZN1S1xE
TX S::x;
// Function parameter references
// CHECK-DAG: _Z1fIiEvT_DtfL0p_E
template <class T> void f(T p, decltype(p));
template <> void f(int p, decltype(p)) {}
// CHECK-DAG: _Z1gIiEvT_PFDtfL0p_EvE
template <class T> void g(T p, decltype(p) (*)());
template <> void g(int p, decltype(p) (*)()) {}
// CHECK-DAG: _Z1hIiEvT_PFDtfL0p_EvE
template <class T> void h(T p, auto (*)()->decltype(p));
template <> void h(int p, auto (*)()->decltype(p)) {}
// CHECK-DAG: _Z1iIiEvT_PFDtfp_ES0_E
template <class T> void i(T p, auto (*)(T q)->decltype(q));
template <> void i(int p, auto (*)(int q)->decltype(q)) {}
// CHECK-DAG: _Z1jIiEvT_PFS0_DtfL1p_EE
template <class T> void j(T p, auto (*)(decltype(p))->T);
template <> void j(int p, auto (*)(decltype(p))->int) {}
// CHECK-DAG: _Z1kIiEvT_PFPAszfL0p__iS0_E
template <class T> void k(T p, int (*(*)(T p))[sizeof(p)]);
template <> void k(int p, int (*(*)(int p))[sizeof(p)]) {}
// CHECK-DAG: _Z1lIiEvT_PDtfL0pK_E
template<typename T> void l(T const p, decltype(p)*);
template <> void l(int p, int const *) {}
// Multiple function parameter references
// CHECK-DAG: _Z1mIiEvT_DtfL0p_ES0_DtfL0p1_E
template <class T> void m(T p, decltype(p), T q, decltype(q));
template <> void m(int p, decltype(p), int q, decltype(q)) {}
// CHECK-DAG: _Z1nIiEvT_PFDtfp0_ES0_S0_E
template <class T> void n(T p, auto (*)(T q, T r)->decltype(r));
template <> void n(int p, auto (*)(int q, int r)->decltype(r)) {}
// CHECK-DAG: _Z1oIiEvfT_PFDtfp0_EcS0_EPFDtfL0p0_ES0_E
template <class T> void o(float f, T p, auto (*)(char c, T q)->decltype(q), auto (*)(T q)->decltype(p));
template <> void o(float f, int p, auto (*)(char c, int q)->decltype(q), auto (*)(int q)->decltype(p)) {}
// CHECK-DAG: _Z3fffIP2S2EDtptfp_1xET_
struct S2 { long double x; };
template<class T> auto fff(T p)->decltype(p->x);
template <> auto fff(S2 *p)->decltype(p->x) { return 0; }
// CHECK-DAG: _Z3gggIN1N1XEEDtsrNT_1XE1yES2_
namespace N {
struct X {
long y;
};
}
template<class T> auto ggg(T p)->decltype(T::X::y);
template<> auto ggg(N::X p)->decltype(N::X::y) { return 0; }
// CHECK-DAG: _ZN1A1fIPNS_1DEEEDtptfp_gssr1A1BE1xET_
namespace A {
struct B { int x; };
struct D : public B {};
template<class T> auto f(T p)->decltype(p->::A::B::x);
template <> auto f<D*>(D* p)->decltype(p->::A::B::x) { return 0; }
}
// CHECK-DAG: _Z3hhhI1QEDTpldtfp_1xdtL_Z1qE1xET_
struct Q {int x; } q;
template<class T> auto hhh(T p)->decltype(p.x + q.x);
template <> auto hhh(Q p)->decltype(p.x + q.x) { return 0; }
// CHECK-DAG: _Z3jjjIiEDTplfp_dtL_Z1dEsr1B1XIT_EE1xES0_
template<class T> struct X { static T x; };
struct B: X<int> {};
struct D: B {} d;
template<class T> auto jjj(T p)->decltype(p+d.B::X<T>::x);
template<> auto jjj(int p)->decltype(p+d.B::X<int>::x) { return 0; }
// new auto
// CHECK-DAG: _Z2kkIN1N1XEEvDTnw_DapicvT__EEE
template <typename T> void kk(decltype(new auto(T())) p) {}
template <> void kk<N::X>(N::X*) {}
// CHECK-DAG: _Z4foouDs
void foou(char16_t) {}
// CHECK-DAG: _Z4foouDi
void foou(char32_t) {}
namespace C {
struct XX {
struct Y {
};
};
struct Z {
XX x;
};
// CHECK-DAG: _ZN1C1fIPNS_1ZEEENDtptfp_1xE1YET_
template<class T> auto f(T p)->typename decltype(p->x)::Y;
template <> auto f<Z*>(Z* p)->decltype(p->x)::Y {}
// CHECK-DAG: _ZN1C1fIPNS_1ZEEEvT_NDtptfL0p_1xE1YE
template<class T> void f(T p, typename decltype(p->x)::Y);
template <> void f<Z*>(Z* p, decltype(p->x)::Y) {}
};
// CHECK-DAG: _Zli8_literaly
unsigned long long operator"" _literal(unsigned long long i) { return i; }
// compiles on clang but not on g++
// is an example in the ABI document.
// ref-qualifier from n2439
// CHECK-DAG: _Z1fM2A2KFvvRE
struct A2 {};
void f(void (A2::*)() const &) {}
// CHECK-DAG: _Z1fM2A2KFvvOE
void f(void (A2::*)() const &&) {}