mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-09-24 19:40:10 +01:00
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:
@@ -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);
|
||||
|
||||
@@ -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
@@ -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
@@ -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]
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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) {}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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";
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user