Repository: carbon-language/carbon-lang
File: toolchain/check/cpp/macros.cpp (C++)

Code before:
                                /*IsReinject=*/false);
  parser.ConsumeAnyToken(true);

  clang::ExprResult result = parser.ParseConstantExpression();
  clang::Expr* result_expr = result.get();

  bool success =
      !result.isInvalid() && parser.getCurToken().is(clang::tok::eof);

  if (!success) {
    parser.SkipUntil(clang::tok::eof);
    CARBON_DIAGNOSTIC(
        InCppMacroEvaluation, Error,
        "failed to evaluate macro Cpp.{0} to a valid constant expression",
        std::string);
    context.emitter().Emit(loc_id, InCppMacroEvaluation, (*name_str_opt).str());
    return nullptr;
  }

  clang::Expr::EvalResult evaluated_result;
  if (result_expr->EvaluateAsInt(evaluated_result, sema.getASTContext())) {
    return clang::IntegerLiteral::Create(
        sema.getASTContext(), evaluated_result.Val.getInt(),
        result_expr->getType(), result_expr->getExprLoc());
  }
  llvm::APFloat ap_value(0.0);
  if (result_expr->EvaluateAsFloat(ap_value, sema.getASTContext())) {
    return clang::FloatingLiteral::Create(
        sema.getASTContext(), ap_value,
        /*isExact=*/true, result_expr->getType(), result_expr->getExprLoc());
  }

  context.TODO(loc_id, "Unsupported: constant type:" +
                           result_expr->getType().getAsString());
  return nullptr;
}

}  // namespace Carbon::Check


Review comment (suggestion):
Just to note, if this remains (might be moot for below comment), there's APInt too so probably better to say "float" instead of just "value"
```suggestion
  llvm::APFloat ap_float(0.0);
```

Code after:
  preprocessor.EnterTokenStream(tokens, /*DisableMacroExpansion=*/false,
                                /*IsReinject=*/false);
  parser.ConsumeAnyToken(true);

  clang::ExprResult result = parser.ParseConstantExpression();
  clang::Expr* result_expr = result.get();

  bool success =
      !result.isInvalid() && parser.getCurToken().is(clang::tok::eof);

  if (!success) {
    parser.SkipUntil(clang::tok::eof);
    CARBON_DIAGNOSTIC(
        InCppMacroEvaluation, Error,
        "failed to parse macro Cpp.{0} to a valid constant expression",
        std::string);
    context.emitter().Emit(loc_id, InCppMacroEvaluation, (*name_str_opt).str());
    return nullptr;
  }

  clang::Expr::EvalResult evaluated_result;
  CARBON_CHECK(result_expr->EvaluateAsConstantExpr(evaluated_result,
                                                   sema.getASTContext()));
  clang::APValue ap_value = evaluated_result.Val;
  switch (ap_value.getKind()) {
    case clang::APValue::Int:
      return clang::IntegerLiteral::Create(
          sema.getASTContext(), ap_value.getInt(), result_expr->getType(),
          result_expr->getExprLoc());
    case clang::APValue::Float:
      return clang::FloatingLiteral::Create(
          sema.getASTContext(), ap_value.getFloat(),
          /*isExact=*/true, result_expr->getType(), result_expr->getExprLoc());
    default:
      context.TODO(loc_id,
                   "Unsupported: macro evaluated to a constant of type: " +
                       result_expr->getType().getAsString());
      return nullptr;
  }
}

}  // namespace Carbon::Check