| // RUN: %clang_cc1 -std=gnu++2a -emit-pch %s -o %t.pch |
| // RUN: %clang_cc1 -std=gnu++2a %s -DEMIT -ast-merge %t.pch -ast-dump-all | FileCheck %s |
| |
| // XFAIL: * |
| |
| #ifndef EMIT |
| #define EMIT |
| |
| namespace Integer { |
| |
| consteval int fint() { |
| return 6789; |
| } |
| |
| int Unique_Int = fint(); |
| //CHECK: VarDecl {{.*}} Unique_Int |
| //CHECK-NEXT: ConstantExpr {{.*}} 'int' |
| //CHECK-NEXT: value: Int 6789 |
| |
| consteval __uint128_t fint128() { |
| return ((__uint128_t)0x75f17d6b3588f843 << 64) | 0xb13dea7c9c324e51; |
| } |
| |
| constexpr __uint128_t Unique_Int128 = fint128(); |
| //CHECK: VarDecl {{.*}} Unique_Int128 |
| //CHECK-NEXT: value: Int 156773562844924187900898496343692168785 |
| //CHECK-NEXT: ConstantExpr |
| //CHECK-NEXT: value: Int 156773562844924187900898496343692168785 |
| |
| } // namespace Integer |
| |
| namespace FloatingPoint { |
| |
| consteval double fdouble() { |
| return double(567890.67890); |
| } |
| |
| double Unique_Double = fdouble(); |
| //CHECK: VarDecl {{.*}} Unique_Double |
| //CHECK-NEXT: ConstantExpr {{.*}} |
| //CHECK-NEXT: value: Float 5.678907e+05 |
| |
| } // namespace FloatingPoint |
| |
| // FIXME: Add test for FixedPoint, ComplexInt, ComplexFloat, AddrLabelDiff. |
| |
| namespace Struct { |
| |
| struct B { |
| int i; |
| double d; |
| }; |
| |
| consteval B fB() { |
| return B{1, 0.7}; |
| } |
| |
| constexpr B Basic_Struct = fB(); |
| //CHECK: VarDecl {{.*}} Basic_Struct |
| //CHECK-NEXT: value: Struct |
| //CHECK-NEXT: fields: Int 1, Float 7.000000e-01 |
| //CHECK-NEXT: ImplicitCastExpr |
| //CHECK-NEXT: ConstantExpr |
| //CHECK-NEXT: value: Struct |
| //CHECK-NEXT: fields: Int 1, Float 7.000000e-01 |
| |
| struct C { |
| int i = 9; |
| }; |
| |
| struct A : B { |
| constexpr A(B b, int I, double D, C _c) : B(b), i(I), d(D), c(_c) {} |
| int i; |
| double d; |
| C c; |
| }; |
| |
| consteval A fA() { |
| return A(Basic_Struct, 1, 79.789, {}); |
| } |
| |
| A Advanced_Struct = fA(); |
| //CHECK: VarDecl {{.*}} Advanced_Struct |
| //CHECK-NEXT: ConstantExpr {{.*}} |
| //CHECK-NEXT: value: Struct |
| //CHECK-NEXT: base: Struct |
| //CHECK-NEXT: fields: Int 1, Float 7.000000e-01 |
| //CHECK-NEXT: fields: Int 1, Float 7.978900e+01 |
| //CHECK-NEXT: field: Struct |
| //CHECK-NEXT: field: Int 9 |
| |
| } // namespace Struct |
| |
| namespace Vector { |
| |
| using v4si = int __attribute__((__vector_size__(16))); |
| |
| consteval v4si fv4si() { |
| return (v4si){8, 2, 3}; |
| } |
| |
| v4si Vector_Int = fv4si(); |
| //CHECK: VarDecl {{.*}} Vector_Int |
| //CHECK-NEXT: ConstantExpr |
| //CHECK-NEXT: value: Vector length=4 |
| //CHECK-NEXT: elements: Int 8, Int 2, Int 3, Int 0 |
| |
| } // namespace Vector |
| |
| namespace Array { |
| |
| struct B { |
| int arr[6]; |
| }; |
| |
| consteval B fint() { |
| return B{1, 2, 3, 4, 5, 6}; |
| } |
| |
| B Array_Int = fint(); |
| //CHECK: VarDecl {{.*}} Array_Int |
| //CHECK-NEXT: ConstantExpr |
| //CHECK-NEXT: value: Struct |
| //CHECK-NEXT: field: Array size=6 |
| //CHECK-NEXT: elements: Int 1, Int 2, Int 3, Int 4 |
| //CHECK-NEXT: elements: Int 5, Int 6 |
| |
| struct A { |
| int i = 789; |
| double d = 67890.09876; |
| }; |
| |
| struct C { |
| A arr[3]; |
| }; |
| |
| consteval C fA() { |
| return {{A{}, A{-45678, 9.8}, A{9}}}; |
| } |
| |
| C Array2_Struct = fA(); |
| //CHECK: VarDecl {{.*}} Array2_Struct |
| //CHECK-NEXT: ConstantExpr {{.*}} |
| |
| using v4si = int __attribute__((__vector_size__(16))); |
| |
| struct D { |
| v4si arr[2]; |
| }; |
| |
| consteval D fv4si() { |
| return {{{1, 2, 3, 4}, {4, 5, 6, 7}}}; |
| } |
| |
| D Array_Vector = fv4si(); |
| //CHECK: VarDecl {{.*}} Array_Vector |
| //CHECK-NEXT: ConstantExpr {{.*}} |
| //CHECK-NEXT: value: Struct |
| //CHECK-NEXT: field: Array size=2 |
| //CHECK-NEXT: element: Vector length=4 |
| //CHECK-NEXT: elements: Int 1, Int 2, Int 3, Int 4 |
| //CHECK-NEXT: element: Vector length=4 |
| //CHECK-NEXT: elements: Int 4, Int 5, Int 6, Int 7 |
| |
| } // namespace Array |
| |
| namespace Union { |
| |
| struct A { |
| int i = 6789; |
| float f = 987.9876; |
| }; |
| |
| union U { |
| int i; |
| A a{567890, 9876.5678f}; |
| }; |
| |
| consteval U fU1() { |
| return U{0}; |
| } |
| |
| U Unique_Union1 = fU1(); |
| //CHECK: VarDecl {{.*}} Unique_Union |
| //CHECK-NEXT: ConstantExpr |
| //CHECK-NEXT: value: Union .i Int 0 |
| |
| consteval U fU() { |
| return U{}; |
| } |
| |
| U Unique_Union2 = fU(); |
| //CHECK: VarDecl {{.*}} Unique_Union |
| //CHECK-NEXT: ConstantExpr |
| //CHECK-NEXT: value: Union .a |
| //CHECK-NEXT: Struct |
| //CHECK-NEXT: fields: Int 567890, Float 9.876567e+03 |
| |
| } // namespace Union |
| |
| namespace MemberPointer { |
| |
| struct A { |
| struct B { |
| struct C { |
| struct D { |
| struct E { |
| struct F { |
| struct G { |
| int i; |
| }; |
| }; |
| }; |
| }; |
| }; |
| }; |
| }; |
| |
| consteval auto fmem_ptr() -> decltype(&A::B::C::D::E::F::G::i) { |
| return &A::B::C::D::E::F::G::i; |
| } |
| |
| auto MemberPointer1 = fmem_ptr(); |
| //CHECK: VarDecl {{.*}} MemberPointer1 |
| //CHECK-NEXT: ConstantExpr |
| //CHECK-NEXT: value: MemberPointer &G::i |
| |
| struct A1 { |
| struct B1 { |
| int f() const { |
| return 0; |
| } |
| }; |
| }; |
| |
| consteval auto fmem_ptr2() { |
| return &A1::B1::f; |
| } |
| |
| auto MemberPointer2 = fmem_ptr2(); |
| //CHECK: VarDecl {{.*}} MemberPointer2 |
| //CHECK-NEXT: ConstantExpr |
| //CHECK-NEXT: value: MemberPointer &B1::f |
| |
| } // namespace MemberPointer |
| |
| namespace std { |
| struct type_info; |
| }; |
| |
| namespace LValue { |
| |
| constexpr int g = 0; |
| |
| consteval const int &fg_ref() { |
| return g; |
| } |
| |
| const int &g_ref = fg_ref(); |
| //CHECK: VarDecl {{.*}} g_ref |
| //CHECK-NEXT: ConstantExpr |
| //CHECK-NEXT: value: LValue &g |
| |
| consteval const int *fint_ptr() { |
| return &g; |
| } |
| |
| const int *g_ptr = fint_ptr(); |
| //CHECK: VarDecl {{.*}} g_ptr |
| //CHECK-NEXT: ConstantExpr |
| //CHECK-NEXT: value: LValue &g |
| |
| consteval const int *fnull_ptr() { |
| return nullptr; |
| } |
| |
| const int *ptr2 = fnull_ptr(); |
| //CHECK: VarDecl {{.*}} ptr2 |
| //CHECK-NEXT: ConstantExpr |
| //CHECK-NEXT: value: LValue nullptr |
| |
| int fconst(); |
| |
| consteval auto ffunc_ptr() { |
| return &fconst; |
| } |
| |
| int (*func_ptr)() = ffunc_ptr(); |
| //CHECK: VarDecl {{.*}} func_ptr |
| //CHECK-NEXT: ConstantExpr {{.*}} |
| //CHECK-NEXT: value: LValue &fconst |
| |
| struct A { |
| int Arr[6] = {0, 1, 3, 4, 5, 9}; |
| int i = 0; |
| }; |
| |
| struct D { |
| A arr[6] = {}; |
| }; |
| |
| consteval D fA() { |
| return {}; |
| } |
| |
| constexpr D Arr = fA(); |
| // CHECK: VarDecl {{.*}} Arr |
| // CHECK-NEXT: value: Struct |
| // CHECK-NEXT: field: Array size=6 |
| // CHECK-NEXT: element: Struct |
| // CHECK-NEXT: field: Array size=6 |
| // CHECK-NEXT: elements: Int 0, Int 1, Int 3, Int 4 |
| // CHECK-NEXT: elements: Int 5, Int 9 |
| // CHECK-NEXT: field: Int 0 |
| // CHECK-NEXT: element: Struct |
| // CHECK-NEXT: field: Array size=6 |
| // CHECK-NEXT: elements: Int 0, Int 1, Int 3, Int 4 |
| // CHECK-NEXT: elements: Int 5, Int 9 |
| // CHECK-NEXT: field: Int 0 |
| // CHECK-NEXT: element: Struct |
| // CHECK-NEXT: field: Array size=6 |
| // CHECK-NEXT: elements: Int 0, Int 1, Int 3, Int 4 |
| // CHECK-NEXT: elements: Int 5, Int 9 |
| // CHECK-NEXT: field: Int 0 |
| // CHECK-NEXT: element: Struct |
| // CHECK-NEXT: field: Array size=6 |
| // CHECK-NEXT: elements: Int 0, Int 1, Int 3, Int 4 |
| // CHECK-NEXT: elements: Int 5, Int 9 |
| // CHECK-NEXT: field: Int 0 |
| // CHECK-NEXT: element: Struct |
| // CHECK-NEXT: field: Array size=6 |
| // CHECK-NEXT: elements: Int 0, Int 1, Int 3, Int 4 |
| // CHECK-NEXT: elements: Int 5, Int 9 |
| // CHECK-NEXT: field: Int 0 |
| // CHECK-NEXT: element: Struct |
| // CHECK-NEXT: field: Array size=6 |
| // CHECK-NEXT: elements: Int 0, Int 1, Int 3, Int 4 |
| // CHECK-NEXT: elements: Int 5, Int 9 |
| // CHECK-NEXT: field: Int 0 |
| // CHECK-NEXT: ImplicitCastExpr |
| // CHECK-NEXT: ConstantExpr |
| // CHECK-NEXT: value: Struct |
| // CHECK-NEXT: field: Array size=6 |
| // CHECK-NEXT: element: Struct |
| // CHECK-NEXT: field: Array size=6 |
| // CHECK-NEXT: elements: Int 0, Int 1, Int 3, Int 4 |
| // CHECK-NEXT: elements: Int 5, Int 9 |
| // CHECK-NEXT: field: Int 0 |
| // CHECK-NEXT: element: Struct |
| // CHECK-NEXT: field: Array size=6 |
| // CHECK-NEXT: elements: Int 0, Int 1, Int 3, Int 4 |
| // CHECK-NEXT: elements: Int 5, Int 9 |
| // CHECK-NEXT: field: Int 0 |
| // CHECK-NEXT: element: Struct |
| // CHECK-NEXT: field: Array size=6 |
| // CHECK-NEXT: elements: Int 0, Int 1, Int 3, Int 4 |
| // CHECK-NEXT: elements: Int 5, Int 9 |
| // CHECK-NEXT: field: Int 0 |
| // CHECK-NEXT: element: Struct |
| // CHECK-NEXT: field: Array size=6 |
| // CHECK-NEXT: elements: Int 0, Int 1, Int 3, Int 4 |
| // CHECK-NEXT: elements: Int 5, Int 9 |
| // CHECK-NEXT: field: Int 0 |
| // CHECK-NEXT: element: Struct |
| // CHECK-NEXT: field: Array size=6 |
| // CHECK-NEXT: elements: Int 0, Int 1, Int 3, Int 4 |
| // CHECK-NEXT: elements: Int 5, Int 9 |
| // CHECK-NEXT: field: Int 0 |
| // CHECK-NEXT: element: Struct |
| // CHECK-NEXT: field: Array size=6 |
| // CHECK-NEXT: elements: Int 0, Int 1, Int 3, Int 4 |
| // CHECK-NEXT: elements: Int 5, Int 9 |
| // CHECK-NEXT: field: Int 0 |
| |
| consteval const int &fconstintref() { |
| return Arr.arr[0].i; |
| } |
| |
| const int &ArrayStructRef1 = fconstintref(); |
| //CHECK: VarDecl {{.*}} ArrayStructRef1 |
| //CHECK-NEXT: ConstantExpr |
| //CHECK-NEXT: value: LValue &Arr.arr[0].i |
| |
| consteval const int &fconstintref2() { |
| return Arr.arr[1].Arr[5]; |
| } |
| |
| const int &ArrayStructRef2 = fconstintref2(); |
| //CHECK: VarDecl {{.*}} ArrayStructRef2 |
| //CHECK-NEXT: ConstantExpr |
| //CHECK-NEXT: value: LValue &Arr.arr[1].Arr[5] |
| |
| consteval const int *fconststar() { |
| return &ArrayStructRef2; |
| } |
| |
| const int *ArrayStructRef3 = fconststar(); |
| //CHECK: VarDecl {{.*}} ArrayStructRef3 |
| //CHECK-NEXT: ConstantExpr |
| //CHECK-NEXT: value: LValue &Arr.arr[1].Arr[5] |
| |
| struct B : A { |
| }; |
| |
| struct C { |
| B b; |
| }; |
| |
| consteval C fC() { |
| return {}; |
| } |
| |
| C c = fC(); |
| //CHECK: VarDecl {{.*}} c |
| //CHECK-NEXT: ConstantExpr |
| //CHECK-NEXT: value: Struct |
| //CHECK-NEXT: field: Struct |
| //CHECK-NEXT: base: Struct |
| //CHECK-NEXT: field: Array size=6 |
| //CHECK-NEXT: elements: Int 0, Int 1, Int 3, Int 4 |
| //CHECK-NEXT: elements: Int 5, Int 9 |
| //CHECK-NEXT: field: Int 0 |
| |
| consteval const int &f2constintref() { |
| return c.b.i; |
| } |
| |
| const int &StructPathRef = f2constintref(); |
| //CHECK: VarDecl {{.*}} StructPathRef |
| //CHECK-NEXT: ConstantExpr |
| //CHECK-NEXT: value: LValue &c.b.A::i |
| |
| consteval const std::type_info *ftype_info() { |
| return &typeid(c); |
| } |
| |
| const std::type_info *T1 = ftype_info(); |
| //CHECK: VarDecl {{.*}} T1 |
| //CHECK-NEXT: ConstantExpr |
| //CHECK-NEXT:value: LValue &typeid(LValue::C) |
| |
| consteval const std::type_info *ftype_info2() { |
| return &typeid(Arr.arr[1].Arr[2]); |
| } |
| |
| const std::type_info *T2 = ftype_info2(); |
| //CHECK: VarDecl {{.*}} T2 |
| //CHECK-NEXT: ConstantExpr |
| //CHECK-NEXT: value: LValue &typeid(int) |
| |
| consteval const char *fstring() { |
| return "test"; |
| } |
| |
| const char *cptr = fstring(); |
| //CHECK: VarDecl {{.*}} cptr |
| //CHECK-NEXT: ConstantExpr |
| //CHECK-NEXT: value: LValue &"test"[0] |
| |
| } // namespace LValue |
| |
| #endif |