463 lines
9.9 KiB
C++
463 lines
9.9 KiB
C++
// 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
|