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

Add support for importing a trivial global C++ function #5033

Merged
merged 18 commits into from
Mar 3, 2025

Conversation

bricknerb
Copy link
Contributor

@bricknerb bricknerb commented Feb 27, 2025

ASTUnit is owned by CompileSubcommand, passed through Unit to be populated in ImportCppFiles() and used via SemIR::File.
When generating the AST, pass -x c++ args to compile C++ (temporary until we pass args properly).
Cpp namespace is marked as a special namespace and has dedicated logic in LookupNameInExactScope().
The logic for importing declarations from C++ to Carbon is in import_cpp.cpp, but we're likely to want to refactor this signfiicantly over time as it grows (perhaps a dedicated directory?).

Part of #4666.

ASTUnit is owned by `CompileSubcommand`, passed through `Unit` to be populated in `ImportCppFiles()` and used via `SemIR::File`.
When generating the AST, pass `-x c++` args to compile C++ (temporary until we pass args properly).
`Cpp` namespace is marked as a special namespace and has dedicated logic in `LookupNameInExactScope()`.
The logic for importing declarations from C++ to Carbon is in `import_cpp.cpp`, but we're likely to want to refactor this signfiicantly over time as it grows (perhaps a dedicated directory?).
@github-actions github-actions bot requested a review from zygoloid February 27, 2025 15:57
@bricknerb bricknerb changed the title Add support for import a trivial global C++ function Add support for importing a trivial global C++ function Feb 27, 2025
Copy link
Contributor

@zygoloid zygoloid left a comment

Choose a reason for hiding this comment

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

Very exciting, this looks like a great step :)

clang::Sema& sema = ast->getSema();

auto name = context.names().GetAsStringIfIdentifier(name_id);
CARBON_CHECK(name);
Copy link
Contributor

Choose a reason for hiding this comment

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

What happens if we try to look up a non-identifier Carbon name, such as via Cpp.Self or Cpp.base? Perhaps we should produce a lookup failure for non-identifier names for now.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Added a test and now using GetIRBaseName().

Copy link
Contributor

Choose a reason for hiding this comment

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

My general understanding is we want to require raw keyword syntax in this sort of situation: i.e., Cpp.r#base, with Cpp.base being an error. So GetAsStringIfIdentifier was correct, rather than GetIRBaseName (which I think mainly exists for debug output).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.

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.

Similarly, nice to see progress here! I realize I missed the publish button though.

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.

If you want to address final comments and merge, that seems fine. Note I've suggested a significant change not to use GetIRBaseName (explanation: #5033 (comment))

Comment on lines 66 to 67
{// Parse C++ (and not C)
"-x", "c++"},
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
{// Parse C++ (and not C)
"-x", "c++"},
// Parse C++ (and not C).
{"-x", "c++"},

Per style: "Only use line comments (with //, not /* ... */), on a line by themselves"
https://github.com/carbon-language/carbon-lang/blob/trunk/docs/project/cpp_style_guide.md

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.

clang::Sema& sema = ast->getSema();

auto name = context.names().GetAsStringIfIdentifier(name_id);
CARBON_CHECK(name);
Copy link
Contributor

Choose a reason for hiding this comment

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

My general understanding is we want to require raw keyword syntax in this sort of situation: i.e., Cpp.r#base, with Cpp.base being an error. So GetAsStringIfIdentifier was correct, rather than GetIRBaseName (which I think mainly exists for debug output).

return std::move(generated_ast);
}

// Lookups the given name in the Clang AST. Returns the lookup result if lookup
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
// Lookups the given name in the Clang AST. Returns the lookup result if lookup
// Looks up the given name in the Clang AST. Returns the lookup result if lookup

Small grammar thing.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.

lookup, ast->getASTContext().getTranslationUnitDecl());

if (lookup.isClassLookup()) {
// TODO: When support class lookup, also check access.
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
// TODO: When support class lookup, also check access.
// TODO: To support class lookup, also return the AccessKind for storage.

To be sure, access can't be checked here; that could lead to something like a protected member being incorrectly hidden, when the caller doesn't have access. Instead the AccessKind needs to be part of the returned information so that it can be stored in the lookup table (instead of AccessKind::Public), and then used by lookup to determine access.

(also, small grammar thing -- "to support" or "when supporting")

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.


if (lookup.isClassLookup()) {
// TODO: When support class lookup, also check access.
context.TODO(loc_id, "Unsupported: Lookup in Class");
Copy link
Contributor

Choose a reason for hiding this comment

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

Maybe (given the "unsupported" string):

Suggested change
context.TODO(loc_id, "Unsupported: Lookup in Class");
context.TODO(loc_id, "Unsupported: Lookup in Class");
return std::nullopt;

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.

CARBON_CHECK(ast);
clang::Sema& sema = ast->getSema();

llvm::StringRef name = context.names().GetIRBaseName(name_id);
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
llvm::StringRef name = context.names().GetIRBaseName(name_id);
std::optional<llvm::StringRef> name = context.names().GetAsStringIfIdentifier(name_id);
if (!name) {
// Special names never exist in C++ code.
return std::nullopt;
}

(see comment)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.
I thought of using a dedicated error for this use case to point out this is a special name (and maybe even tell the user how to fix), but keeping as is.
See 16867c9

@bricknerb
Copy link
Contributor Author

If you want to address final comments and merge, that seems fine. Note I've suggested a significant change not to use GetIRBaseName (explanation: #5033 (comment))

Thanks!
I've addressed the final comments and will try to merge.

@bricknerb bricknerb enabled auto-merge March 3, 2025 09:23
@bricknerb bricknerb added this pull request to the merge queue Mar 3, 2025
Merged via the queue into carbon-language:trunk with commit 87b9cab Mar 3, 2025
8 checks passed
@bricknerb bricknerb deleted the interop2 branch March 3, 2025 11:59
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