diff --git a/toolchain/check/cpp/macros.cpp b/toolchain/check/cpp/macros.cpp index 9684f4c7a9e0..15a554b39cf9 100644 --- a/toolchain/check/cpp/macros.cpp +++ b/toolchain/check/cpp/macros.cpp @@ -25,6 +25,7 @@ auto TryEvaluateMacroToConstant(Context& context, SemIR::LocId loc_id, clang::Sema& sema = context.clang_sema(); clang::Preprocessor& preprocessor = sema.getPreprocessor(); + clang::Parser parser(preprocessor, sema, false); llvm::SmallVector tokens(macro_info->tokens().begin(), @@ -45,7 +46,12 @@ auto TryEvaluateMacroToConstant(Context& context, SemIR::LocId loc_id, /*IsReinject=*/false); parser.ConsumeAnyToken(true); + // TODO: Identifiers are still only available if prefixed with "::" (e.g. + // "#define M_Var ::myVar"). + parser.EnterScope(clang::Scope::DeclScope); clang::ExprResult result = parser.ParseConstantExpression(); + parser.ExitScope(); + clang::Expr* result_expr = result.get(); bool success = @@ -70,6 +76,7 @@ auto TryEvaluateMacroToConstant(Context& context, SemIR::LocId loc_id, 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: diff --git a/toolchain/check/testdata/interop/cpp/macros.carbon b/toolchain/check/testdata/interop/cpp/macros.carbon index 141331152f3d..d2069794bc17 100644 --- a/toolchain/check/testdata/interop/cpp/macros.carbon +++ b/toolchain/check/testdata/interop/cpp/macros.carbon @@ -608,6 +608,42 @@ fn F() { Cpp.foo(Cpp.MyNullPtr); } +// --- enums.carbon + +library "[[@TEST_NAME]]"; + +import Cpp inline ''' + enum A { a = 1, b = 2 }; + #define M_A ::a +'''; + +fn F() { + let a: Cpp.A = Cpp.M_A; +} + +// --- fail_todo_enums_no_scope.carbon + +library "[[@TEST_NAME]]"; + +import Cpp inline ''' + enum A { a = 1, b = 2 }; + // CHECK:STDERR: fail_todo_enums_no_scope.carbon:[[@LINE+7]]:24: error: use of undeclared identifier 'a'; did you mean '::a'? [CppInteropParseError] + // CHECK:STDERR: 13 | #define M_A_NO_SCOPE a + // CHECK:STDERR: | ^ + // CHECK:STDERR: | ::a + // CHECK:STDERR: fail_todo_enums_no_scope.carbon:[[@LINE-5]]:12: note: '::a' declared here [CppInteropParseNote] + // CHECK:STDERR: 5 | enum A { a = 1, b = 2 }; + // CHECK:STDERR: | ^ + #define M_A_NO_SCOPE a +'''; + +fn F() { + // CHECK:STDERR: fail_todo_enums_no_scope.carbon:[[@LINE+4]]:3: note: in `Cpp` name lookup for `M_A_NO_SCOPE` [InCppNameLookup] + // CHECK:STDERR: Cpp.M_A_NO_SCOPE; + // CHECK:STDERR: ^~~~~~~~~~~~~~~~ + // CHECK:STDERR: + Cpp.M_A_NO_SCOPE; +} // --- lambda.carbon