macros.cpp 1.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546
  1. // Part of the Carbon Language project, under the Apache License v2.0 with LLVM
  2. // Exceptions. See /LICENSE for license information.
  3. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  4. #include "toolchain/check/cpp/macros.h"
  5. #include "clang/AST/ASTContext.h"
  6. #include "clang/Sema/Sema.h"
  7. namespace Carbon::Check {
  8. auto TryEvaluateMacroToConstant(Context& context, SemIR::LocId loc_id,
  9. SemIR::NameId name_id,
  10. clang::MacroInfo* macro_info) -> clang::Expr* {
  11. auto name_str_opt = context.names().GetAsStringIfIdentifier(name_id);
  12. CARBON_CHECK(macro_info, "macro info missing");
  13. if (macro_info->getNumTokens() != 1) {
  14. context.TODO(loc_id,
  15. llvm::formatv("Unsupported: macro with {0} replacement tokens",
  16. macro_info->getNumTokens()));
  17. return nullptr;
  18. }
  19. const clang::Token& tok = macro_info->getReplacementToken(0);
  20. if (!tok.is(clang::tok::numeric_constant)) {
  21. context.TODO(loc_id,
  22. "Unsupported: macro replacement token kind: " +
  23. std::string(clang::tok::getTokenName(tok.getKind())));
  24. return nullptr;
  25. }
  26. clang::Sema& sema = context.clang_sema();
  27. clang::ExprResult result = sema.ActOnNumericConstant(tok);
  28. clang::Expr* result_expr = result.get();
  29. if (!result_expr || result.isInvalid()) {
  30. CARBON_DIAGNOSTIC(
  31. InCppMacroEvaluation, Error,
  32. "failed to evaluate macro Cpp.{0} to a valid constant expression",
  33. std::string);
  34. context.emitter().Emit(loc_id, InCppMacroEvaluation, (*name_str_opt).str());
  35. return nullptr;
  36. }
  37. return result_expr;
  38. }
  39. } // namespace Carbon::Check