Support import Cpp; to import Cpp namespace for using C++ builtins (#6320)

This allows writing
```
import Cpp;
```

Instead of writing
```
import Cpp inline "";
```

Part of #6330.
This commit is contained in:
Boaz Brickner
2025-11-06 08:45:28 +00:00
committed by GitHub
parent ce109708bf
commit b54f2dd592
11 changed files with 110 additions and 33 deletions
+2 -7
View File
@@ -79,12 +79,6 @@ static auto TrackImport(Map<ImportKey, UnitAndImports*>& api_map,
// have diagnosed the use of `Cpp` in the declaration.
return;
}
if (!import.library_id.has_value() && !import.inline_body_id.has_value()) {
CARBON_DIAGNOSTIC(CppInteropMissingLibrary, Error,
"`Cpp` import without `library` or `inline`");
unit_info.emitter.Emit(import.node_id, CppInteropMissingLibrary);
return;
}
if (fuzzing) {
// Clang is not crash-resilient.
CARBON_DIAGNOSTIC(CppInteropFuzzing, Error,
@@ -94,7 +88,8 @@ static auto TrackImport(Map<ImportKey, UnitAndImports*>& api_map,
}
unit_info.cpp_imports.push_back(import);
return;
} else if (import.inline_body_id.has_value()) {
}
if (import.inline_body_id.has_value()) {
CARBON_DIAGNOSTIC(InlineImportNotCpp, Error,
"`inline` import not in package `Cpp`");
unit_info.emitter.Emit(import.node_id, InlineImportNotCpp);
+1 -1
View File
@@ -102,7 +102,7 @@ static auto GenerateCppIncludesHeaderCode(
<< "\n";
// TODO: Inject a clang pragma here to produce an error if there are
// unclosed scopes at the end of this inline C++ fragment.
} else {
} else if (import.library_id.has_value()) {
// Translate `import Cpp library "foo.h";` into `#include "foo.h"`.
GenerateLineMarker(context, code_stream,
context.tokens().GetLineNumber(
+56 -10
View File
@@ -10,16 +10,6 @@
// TIP: To dump output, run:
// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/check/testdata/interop/cpp/bad_import.carbon
// --- fail_import_cpp.carbon
library "[[@TEST_NAME]]";
// CHECK:STDERR: fail_import_cpp.carbon:[[@LINE+4]]:1: error: `Cpp` import without `library` or `inline` [CppInteropMissingLibrary]
// CHECK:STDERR: import Cpp;
// CHECK:STDERR: ^~~~~~~~~~~
// CHECK:STDERR:
import Cpp;
// --- fail_import_cpp_library_empty.carbon
library "[[@TEST_NAME]]";
@@ -52,3 +42,59 @@ void f() {
import Cpp inline '''c++
}
''';
// --- fail_import_cpp_library_without_name_and_inline_without_content.carbon
library "[[@TEST_NAME]]";
// CHECK:STDERR: fail_import_cpp_library_without_name_and_inline_without_content.carbon:[[@LINE+8]]:20: error: expected a string literal to specify the library name [ExpectedLibraryName]
// CHECK:STDERR: import Cpp library inline;
// CHECK:STDERR: ^~~~~~
// CHECK:STDERR:
// CHECK:STDERR: fail_import_cpp_library_without_name_and_inline_without_content.carbon:[[@LINE+4]]:20: error: semantics TODO: `handle invalid parse trees in `check`` [SemanticsTodo]
// CHECK:STDERR: import Cpp library inline;
// CHECK:STDERR: ^~~~~~
// CHECK:STDERR:
import Cpp library inline;
// --- fail_import_cpp_library_with_name_and_inline_without_content.carbon
library "[[@TEST_NAME]]";
// CHECK:STDERR: fail_import_cpp_library_with_name_and_inline_without_content.carbon:[[@LINE+8]]:28: error: `import` declarations must end with a `;` [ExpectedDeclSemi]
// CHECK:STDERR: import Cpp library "foo.h" inline;
// CHECK:STDERR: ^~~~~~
// CHECK:STDERR:
// CHECK:STDERR: fail_import_cpp_library_with_name_and_inline_without_content.carbon:[[@LINE+4]]:1: error: semantics TODO: `handle invalid parse trees in `check`` [SemanticsTodo]
// CHECK:STDERR: import Cpp library "foo.h" inline;
// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// CHECK:STDERR:
import Cpp library "foo.h" inline;
// --- fail_import_cpp_library_without_name_and_inline_with_content.carbon
library "[[@TEST_NAME]]";
// CHECK:STDERR: fail_import_cpp_library_without_name_and_inline_with_content.carbon:[[@LINE+8]]:20: error: expected a string literal to specify the library name [ExpectedLibraryName]
// CHECK:STDERR: import Cpp library inline "";
// CHECK:STDERR: ^~~~~~
// CHECK:STDERR:
// CHECK:STDERR: fail_import_cpp_library_without_name_and_inline_with_content.carbon:[[@LINE+4]]:20: error: semantics TODO: `handle invalid parse trees in `check`` [SemanticsTodo]
// CHECK:STDERR: import Cpp library inline "";
// CHECK:STDERR: ^~~~~~
// CHECK:STDERR:
import Cpp library inline "";
// --- fail_import_cpp_library_with_name_and_inline_with_content.carbon
library "[[@TEST_NAME]]";
// CHECK:STDERR: fail_import_cpp_library_with_name_and_inline_with_content.carbon:[[@LINE+8]]:28: error: `import` declarations must end with a `;` [ExpectedDeclSemi]
// CHECK:STDERR: import Cpp library "foo.h" inline "";
// CHECK:STDERR: ^~~~~~
// CHECK:STDERR:
// CHECK:STDERR: fail_import_cpp_library_with_name_and_inline_with_content.carbon:[[@LINE+4]]:1: error: semantics TODO: `handle invalid parse trees in `check`` [SemanticsTodo]
// CHECK:STDERR: import Cpp library "foo.h" inline "";
// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// CHECK:STDERR:
import Cpp library "foo.h" inline "";
+3 -3
View File
@@ -14,7 +14,7 @@
library "[[@TEST_NAME]]";
import Cpp inline "";
import Cpp;
fn F() {
//@dump-sem-ir-begin
@@ -48,7 +48,7 @@ fn F() {
library "[[@TEST_NAME]]";
import Cpp inline "";
import Cpp;
fn F() {
//@dump-sem-ir-begin
@@ -68,7 +68,7 @@ fn F() {
library "[[@TEST_NAME]]";
import Cpp inline "";
import Cpp;
fn F() {
// CHECK:STDERR: fail_not_builtin.carbon:[[@LINE+4]]:21: error: member name `not_builtin` not found in `Cpp` [MemberNameNotFoundInInstScope]
+2 -2
View File
@@ -15,7 +15,7 @@
library "[[@TEST_NAME]]";
import Cpp inline "";
import Cpp;
fn F() {
//@dump-sem-ir-begin
@@ -31,7 +31,7 @@ fn F() {
library "[[@TEST_NAME]]";
import Cpp inline "";
import Cpp;
fn F() {
//@dump-sem-ir-begin
+2 -2
View File
@@ -15,7 +15,7 @@
library "[[@TEST_NAME]]";
import Cpp inline "";
import Cpp;
fn F() {
//@dump-sem-ir-begin
@@ -31,7 +31,7 @@ fn F() {
library "[[@TEST_NAME]]";
import Cpp inline "";
import Cpp;
fn F() {
//@dump-sem-ir-begin
@@ -88,7 +88,7 @@ fn F() {
library "[[@TEST_NAME]]";
import Cpp inline "";
import Cpp;
// CHECK:STDERR: fail_void.carbon:[[@LINE+5]]:6: error: parameter has incomplete type `Cpp.void` in function definition [IncompleteTypeInFunctionParam]
// CHECK:STDERR: fn F(x: Cpp.void) {}
+37
View File
@@ -115,6 +115,43 @@ fn F() {
//@dump-sem-ir-end
}
// ============================================================================
// Import Cpp without a header
// ============================================================================
// --- no_header.carbon
library "[[@TEST_NAME]]";
import Cpp;
fn F(input: Cpp.int) {
let output: i32 = input;
}
// ============================================================================
// Import Cpp without a header, with a header and inline
// ============================================================================
// --- header_function.h
auto MyHeaderFunction(int) -> void;
// --- no_header_with_header_inline.carbon
library "[[@TEST_NAME]]";
import Cpp;
import Cpp library "header_function.h";
import Cpp inline '''
auto MyInlineFunction(short) -> void;
''';
fn F() {
Cpp.MyHeaderFunction(8 as Cpp.int);
Cpp.MyInlineFunction(9 as Cpp.short);
}
// CHECK:STDOUT: --- fail_todo_import_struct_api.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: constants {
+2 -2
View File
@@ -35,7 +35,7 @@ fn F(input: Cpp.S*) {
library "[[@TEST_NAME]]";
import Cpp inline "";
import Cpp;
class C {}
@@ -77,7 +77,7 @@ fn F(input: Cpp.void*) {
library "[[@TEST_NAME]]";
import Cpp inline "";
import Cpp;
class C {}
@@ -190,7 +190,6 @@ CARBON_DIAGNOSTIC_KIND(InCppTypeCompletion)
// Package/import checking diagnostics.
CARBON_DIAGNOSTIC_KIND(CppInteropFuzzing)
CARBON_DIAGNOSTIC_KIND(CppInteropMissingLibrary)
CARBON_DIAGNOSTIC_KIND(CppInteropDriverError)
CARBON_DIAGNOSTIC_KIND(CppInteropDriverWarning)
CARBON_DIAGNOSTIC_KIND(CppInteropParseError)
+4 -4
View File
@@ -1260,14 +1260,14 @@ auto Formatter::FormatImportCppDeclRhs() -> void {
}
Indent();
out_ << "import Cpp ";
out_ << "import Cpp";
if (import.library_id.has_value()) {
out_ << "\""
out_ << " \""
<< FormatEscaped(
sem_ir_->string_literal_values().Get(import.library_id))
<< "\"";
} else {
out_ << "inline";
} else if (import.inline_body_id.has_value()) {
out_ << " inline";
}
out_ << "\n";
}