Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Generate AST when importing cpp files #4790

Open
wants to merge 1 commit into
base: trunk
Choose a base branch
from

Conversation

bricknerb
Copy link
Contributor

Ignore the AST, for now.
Report cpp compilation errors and warnings.
Part of #4666

@bricknerb bricknerb requested a review from jonmeow January 10, 2025 15:40
@github-actions github-actions bot requested a review from danakj January 10, 2025 15:41
Ignore the AST, for now.
Report cpp compilation errors and warnings.
Part of carbon-language#4666
Copy link
Contributor

@danakj danakj left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

a couple suggestions and questions

llvm::raw_ostream* vlog_stream)
: unit_and_imports_(unit_and_imports),
total_ir_count_(total_ir_count),
fs_(fs),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
fs_(fs),
fs_(std::move(fs)),

(avoid refcount churn)


auto file = fs_->openFileForRead(cpp_file_path);
if (!file) {
CARBON_DIAGNOSTIC(CppInteropFileNotFound, Error,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
CARBON_DIAGNOSTIC(CppInteropFileNotFound, Error,
CARBON_DIAGNOSTIC(CppInteropCantReadFile, Error,

The text and the name say different things, they could be more similar?

if (num_errors > 0) {
// TODO: Remove the warnings part when there are no warnings.
CARBON_DIAGNOSTIC(
CppInteropCodeErrors, Error,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
CppInteropCodeErrors, Error,
CppInteropParseError, Error,

context.emitter().Emit(loc, CppInteropCodeErrors, num_errors, num_warnings,
file_path.str(), diagnostics_str);
} else if (num_warnings > 0) {
CARBON_DIAGNOSTIC(CppInteropCodeWarnings, Warning,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
CARBON_DIAGNOSTIC(CppInteropCodeWarnings, Warning,
CARBON_DIAGNOSTIC(CppInteropParseWarning, Warning,


library "[[@TEST_NAME]]";

// CHECK:STDERR: fail_cpp_file_not_found.carbon:[[@LINE+3]]:1: error: file 'not_found.h' couldn't be opened for reading: No such file or directory [CppInteropFileNotFound]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the "No such file or directory" reason could move to a note here

llvm::ArrayRef(DiagnosticKinds),
llvm::ArrayRef(UntestedDiagnosticKinds));
Testing::TestKindCoverage(
absl::GetFlag(FLAGS_testdata_manifest), R"( \[([A-Z]\w*)\]$)",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This regex will match most anything now, is it still effectively testing something?

Copy link
Contributor

@jonmeow jonmeow left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is great!

I'm looking at this, and thought of a lateral issue... We're fuzz testing, and as soon as the fuzzer discovers it can write C++ imports we'll end up fuzz testing Clang, and Clang is not crash-resilient. The driver already has a DriverEnv::fuzzing flag, can you have it lead to an error when set and importing from Cpp?

Comment on lines +76 to +82
bool is_cpp =
import_package_name == CppPackageName && !import_library_name.empty();

if (is_cpp) {
unit_info.cpp_imports.push_back(import);
return;
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it make sense to move this above is_explicit_main since is_explicit_main isn't used in this path? Also, does is_cpp need the local or is it only used here? (note for contrast, is_explicit_main is referenced in a few spots)

Comment on lines +76 to +77
bool is_cpp =
import_package_name == CppPackageName && !import_library_name.empty();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you add some tests for things like:

  • import package Cpp; -- should probably be complaining that Cpp needs a library, might complain that there's no api file right now.
  • import package Cpp library ""; - "file not found" seems fine
  • import package Cpp library "\"foo.h\""; - ???

Comment on lines +363 to +364
ImportCppFile(context_, import.node_id, cpp_file_path,
buffer.get()->getBuffer());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Versus loading each C++ file individually, had you considered generating a file like:

  std::string content;
  for (const auto& import : unit_and_imports_->cpp_imports) {
    llvm::StringRef cpp_file_path =
        unit_and_imports_->unit->value_stores->string_literal_values().Get(
            import.library_id);
    content += llvm::formatv("#include \"{0}\"\n", cpp_file_path);
  }
  ImportCppFile(context_, import.node_id, carbon_file_name + '.interop.cpp", content);

One particular consequence of that kind of approach is that if you have something like C++ headers that interact (e.g. one #define's a value, the next has a #ifdef on it) they'd work just like they would in C++. Or if there are overloaded functions, it lets C++ decide how to handle them. Thoughts?

(note, my example uses a simple #include, but down the road we'll want to think about how to work with C++ modules too)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's a good idea. It'll also be faster as it'll have to build/walk an AST once instead of N times, and only has to go through transitive includes once.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants