|  | // 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 |