// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py
// RUN: %clang_cc1 -emit-llvm %s -std=c++2a -triple x86_64-unknown-linux-gnu -o %t.ll
// RUN: FileCheck -check-prefix=EVAL -input-file=%t.ll %s
// RUN: FileCheck -check-prefix=EVAL-STATIC -input-file=%t.ll %s
// RUN: FileCheck -check-prefix=EVAL-FN -input-file=%t.ll %s
//
// RUN: %clang_cc1 -emit-llvm %s -Dconsteval="" -std=c++2a -triple x86_64-unknown-linux-gnu -o %t.ll
// RUN: FileCheck -check-prefix=EXPR -input-file=%t.ll %s

// there is two version of symbol checks to ensure
// that the symbol we are looking for are correct
// EVAL-NOT: @__cxx_global_var_init()
// EXPR: @__cxx_global_var_init()

// EVAL-NOT: @_Z4ret7v()
// EXPR: @_Z4ret7v()
consteval int ret7() {
  return 7;
}

// EVAL-FN-LABEL: @_Z9test_ret7v(
// EVAL-FN-NEXT:  entry:
// EVAL-FN-NEXT:    [[I:%.*]] = alloca i32, align 4
// EVAL-FN-NEXT:    store i32 7, i32* [[I]], align 4
// EVAL-FN-NEXT:    [[TMP0:%.*]] = load i32, i32* [[I]], align 4
// EVAL-FN-NEXT:    ret i32 [[TMP0]]
//
int test_ret7() {
  int i = ret7();
  return i;
}

int global_i = ret7();

constexpr int i_const = 5;

// EVAL-NOT: @_Z4retIv()
// EXPR: @_Z4retIv()
consteval const int &retI() {
  return i_const;
}

// EVAL-FN-LABEL: @_Z12test_retRefIv(
// EVAL-FN-NEXT:  entry:
// EVAL-FN-NEXT:    ret i32* @_ZL7i_const
//
const int &test_retRefI() {
  return retI();
}

// EVAL-FN-LABEL: @_Z9test_retIv(
// EVAL-FN-NEXT:  entry:
// EVAL-FN-NEXT:    [[TMP0:%.*]] = load i32, i32* @_ZL7i_const, align 4
// EVAL-FN-NEXT:    ret i32 [[TMP0]]
//
int test_retI() {
  return retI();
}

// EVAL-NOT: @_Z4retIv()
// EXPR: @_Z4retIv()
consteval const int *retIPtr() {
  return &i_const;
}

// EVAL-FN-LABEL: @_Z12test_retIPtrv(
// EVAL-FN-NEXT:  entry:
// EVAL-FN-NEXT:    [[TMP0:%.*]] = load i32, i32* @_ZL7i_const, align 4
// EVAL-FN-NEXT:    ret i32 [[TMP0]]
//
int test_retIPtr() {
  return *retIPtr();
}

// EVAL-FN-LABEL: @_Z13test_retPIPtrv(
// EVAL-FN-NEXT:  entry:
// EVAL-FN-NEXT:    ret i32* @_ZL7i_const
//
const int *test_retPIPtr() {
  return retIPtr();
}

// EVAL-NOT: @_Z4retIv()
// EXPR: @_Z4retIv()
consteval const int &&retIRRef() {
  return static_cast<const int &&>(i_const);
}

// EVAL-FN-LABEL: @_Z13test_retIRRefv(
// EVAL-FN-NEXT:  entry:
// EVAL-FN-NEXT:    ret i32* @_ZL7i_const
//
const int &&test_retIRRef() {
  return static_cast<const int &&>(retIRRef());
}

// EVAL-FN-LABEL: @_Z14test_retIRRefIv(
// EVAL-FN-NEXT:  entry:
// EVAL-FN-NEXT:    [[TMP0:%.*]] = load i32, i32* @_ZL7i_const, align 4
// EVAL-FN-NEXT:    ret i32 [[TMP0]]
//
int test_retIRRefI() {
  return retIRRef();
}

struct Agg {
  int a;
  long b;
};

// EVAL-NOT: @_Z6retAggv()
// EXPR: @_Z6retAggv()
consteval Agg retAgg() {
  return {13, 17};
}

// EVAL-FN-LABEL: @_Z11test_retAggv(
// EVAL-FN-NEXT:  entry:
// EVAL-FN-NEXT:    [[B:%.*]] = alloca i64, align 8
// EVAL-FN-NEXT:    [[REF_TMP:%.*]] = alloca [[STRUCT_AGG:%.*]], align 8
// EVAL-FN-NEXT:    [[TMP0:%.*]] = getelementptr inbounds [[STRUCT_AGG]], %struct.Agg* [[REF_TMP]], i32 0, i32 0
// EVAL-FN-NEXT:    store i32 13, i32* [[TMP0]], align 8
// EVAL-FN-NEXT:    [[TMP1:%.*]] = getelementptr inbounds [[STRUCT_AGG]], %struct.Agg* [[REF_TMP]], i32 0, i32 1
// EVAL-FN-NEXT:    store i64 17, i64* [[TMP1]], align 8
// EVAL-FN-NEXT:    store i64 17, i64* [[B]], align 8
// EVAL-FN-NEXT:    [[TMP2:%.*]] = load i64, i64* [[B]], align 8
// EVAL-FN-NEXT:    ret i64 [[TMP2]]
//
long test_retAgg() {
  long b = retAgg().b;
  return b;
}

// EVAL-STATIC: @A ={{.*}} global %struct.Agg { i32 13, i64 17 }, align 8
Agg A = retAgg();

// EVAL-NOT: @_Z9retRefAggv()
// EXPR: @_Z9retRefAggv()
consteval const Agg &retRefAgg() {
  const Agg &tmp = A;
  return A;
}

// EVAL-FN-LABEL: @_Z14test_retRefAggv(
// EVAL-FN-NEXT:  entry:
// EVAL-FN-NEXT:    [[B:%.*]] = alloca i64, align 8
// EVAL-FN-NEXT:    [[REF_TMP:%.*]] = alloca [[STRUCT_AGG:%.*]], align 8
// EVAL-FN-NEXT:    [[TMP0:%.*]] = getelementptr inbounds [[STRUCT_AGG]], %struct.Agg* [[REF_TMP]], i32 0, i32 0
// EVAL-FN-NEXT:    store i32 13, i32* [[TMP0]], align 8
// EVAL-FN-NEXT:    [[TMP1:%.*]] = getelementptr inbounds [[STRUCT_AGG]], %struct.Agg* [[REF_TMP]], i32 0, i32 1
// EVAL-FN-NEXT:    store i64 17, i64* [[TMP1]], align 8
// EVAL-FN-NEXT:    store i64 17, i64* [[B]], align 8
// EVAL-FN-NEXT:    [[TMP2:%.*]] = load i64, i64* [[B]], align 8
// EVAL-FN-NEXT:    ret i64 [[TMP2]]
//
long test_retRefAgg() {
  long b = retAgg().b;
  return b;
}

// EVAL-NOT: @_Z8is_constv()
// EXPR: @_Z8is_constv()
consteval Agg is_const() {
  return {5, 19 * __builtin_is_constant_evaluated()};
}

// EVAL-FN-LABEL: @_Z13test_is_constv(
// EVAL-FN-NEXT:  entry:
// EVAL-FN-NEXT:    [[B:%.*]] = alloca i64, align 8
// EVAL-FN-NEXT:    [[REF_TMP:%.*]] = alloca [[STRUCT_AGG:%.*]], align 8
// EVAL-FN-NEXT:    [[TMP0:%.*]] = getelementptr inbounds [[STRUCT_AGG]], %struct.Agg* [[REF_TMP]], i32 0, i32 0
// EVAL-FN-NEXT:    store i32 5, i32* [[TMP0]], align 8
// EVAL-FN-NEXT:    [[TMP1:%.*]] = getelementptr inbounds [[STRUCT_AGG]], %struct.Agg* [[REF_TMP]], i32 0, i32 1
// EVAL-FN-NEXT:    store i64 19, i64* [[TMP1]], align 8
// EVAL-FN-NEXT:    store i64 19, i64* [[B]], align 8
// EVAL-FN-NEXT:    [[TMP2:%.*]] = load i64, i64* [[B]], align 8
// EVAL-FN-NEXT:    ret i64 [[TMP2]]
//
long test_is_const() {
  long b = is_const().b;
  return b;
}

// EVAL-NOT: @_ZN7AggCtorC
// EXPR: @_ZN7AggCtorC
struct AggCtor {
  consteval AggCtor(int a = 3, long b = 5) : a(a * a), b(a * b) {}
  int a;
  long b;
};

// EVAL-FN-LABEL: @_Z12test_AggCtorv(
// EVAL-FN-NEXT:  entry:
// EVAL-FN-NEXT:    [[I:%.*]] = alloca i32, align 4
// EVAL-FN-NEXT:    [[C:%.*]] = alloca [[STRUCT_AGGCTOR:%.*]], align 8
// EVAL-FN-NEXT:    store i32 2, i32* [[I]], align 4
// EVAL-FN-NEXT:    [[TMP0:%.*]] = getelementptr inbounds [[STRUCT_AGGCTOR]], %struct.AggCtor* [[C]], i32 0, i32 0
// EVAL-FN-NEXT:    store i32 4, i32* [[TMP0]], align 8
// EVAL-FN-NEXT:    [[TMP1:%.*]] = getelementptr inbounds [[STRUCT_AGGCTOR]], %struct.AggCtor* [[C]], i32 0, i32 1
// EVAL-FN-NEXT:    store i64 10, i64* [[TMP1]], align 8
// EVAL-FN-NEXT:    [[A:%.*]] = getelementptr inbounds [[STRUCT_AGGCTOR]], %struct.AggCtor* [[C]], i32 0, i32 0
// EVAL-FN-NEXT:    [[TMP2:%.*]] = load i32, i32* [[A]], align 8
// EVAL-FN-NEXT:    [[CONV:%.*]] = sext i32 [[TMP2]] to i64
// EVAL-FN-NEXT:    [[B:%.*]] = getelementptr inbounds [[STRUCT_AGGCTOR]], %struct.AggCtor* [[C]], i32 0, i32 1
// EVAL-FN-NEXT:    [[TMP3:%.*]] = load i64, i64* [[B]], align 8
// EVAL-FN-NEXT:    [[ADD:%.*]] = add nsw i64 [[CONV]], [[TMP3]]
// EVAL-FN-NEXT:    ret i64 [[ADD]]
//
long test_AggCtor() {
  const int i = 2;
  AggCtor C(i);
  return C.a + C.b;
}

struct UserConv {
  consteval operator int() const noexcept { return 42; }
};

// EVAL-FN-LABEL: @_Z13test_UserConvv(
// EVAL-FN-NEXT:  entry:
// EVAL-FN-NEXT:    ret i32 42
//
int test_UserConv() {
  return UserConv();
}

int test_UserConvOverload_helper(int a) { return a; }

// EVAL-FN-LABEL: @_Z21test_UserConvOverloadv(
// EVAL-FN-NEXT:  entry:
// EVAL-FN-NEXT:    %call = call i32 @_Z28test_UserConvOverload_helperi(i32 42)
// EVAL-FN-NEXT:    ret i32 %call
//
int test_UserConvOverload() {
  return test_UserConvOverload_helper(UserConv());
}

consteval int test_UserConvOverload_helper_ceval(int a) { return a; }

// EVAL-FN-LABEL: @_Z27test_UserConvOverload_cevalv(
// EVAL-FN-NEXT:  entry:
// EVAL-FN-NEXT:    ret i32 42
//
int test_UserConvOverload_ceval() {
  return test_UserConvOverload_helper_ceval(UserConv());
}

consteval void void_test() {}
void void_call() { // EVAL-FN-LABEL: define {{.*}} @_Z9void_call
  // EVAL-FN-NOT: call
  void_test();
  // EVAL-FN: {{^}}}
}
