mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-09-24 22:02:23 +01:00
Implement support for copying C++ classes. (#6434)
When performing impl lookup for `Core.Copy` for a C++ class type, look for a copy constructor. If we find one, synthesize an impl witness that calls the constructor. This adds initial support for impl lookup to delegate to the C++ interop logic for queries involving C++ types. For now, we don't implement the rules from #6166 that compare a synthesized type structure for the C++ impl against the best Carbon type structure, but the framework for building that support is established here. Currently there is no caching of the lookup here, and we build unique `ImplWitnessTable`s for each lookup, which leads to each impl lookup producing a distinct facet value. This results in some errors in generic contexts; this will be addressed in follow-up changes. This PR aims only to support the non-generic case. --------- Co-authored-by: Dana Jansens <danakj@orodu.net> Co-authored-by: Carbon Infra Bot <carbon-external-infra@google.com>
This commit is contained in:
co-authored by
Dana Jansens
Carbon Infra Bot
parent
19660ccde0
commit
372f632d9d
@@ -25,7 +25,7 @@ static auto GetClangOperatorKind(Context& context, SemIR::LocId loc_id,
|
||||
-> std::optional<clang::OverloadedOperatorKind> {
|
||||
// Unary operators.
|
||||
if (interface_name == "Destroy" || interface_name == "As" ||
|
||||
interface_name == "ImplicitAs") {
|
||||
interface_name == "ImplicitAs" || interface_name == "Copy") {
|
||||
// TODO: Support destructors and conversions.
|
||||
return std::nullopt;
|
||||
}
|
||||
@@ -280,17 +280,37 @@ auto IsCppOperatorMethodDecl(clang::Decl* decl) -> bool {
|
||||
return clang_method_decl && clang_method_decl->isOverloadedOperator();
|
||||
}
|
||||
|
||||
auto IsCppOperatorMethod(Context& context, SemIR::InstId inst_id) -> bool {
|
||||
static auto GetAsCppFunctionDecl(Context& context, SemIR::InstId inst_id)
|
||||
-> clang::FunctionDecl* {
|
||||
auto function_type = context.types().TryGetAs<SemIR::FunctionType>(
|
||||
context.insts().Get(inst_id).type_id());
|
||||
if (!function_type) {
|
||||
return false;
|
||||
return nullptr;
|
||||
}
|
||||
SemIR::ClangDeclId clang_decl_id =
|
||||
context.functions().Get(function_type->function_id).clang_decl_id;
|
||||
return clang_decl_id.has_value() &&
|
||||
IsCppOperatorMethodDecl(
|
||||
context.clang_decls().Get(clang_decl_id).key.decl);
|
||||
return clang_decl_id.has_value()
|
||||
? dyn_cast<clang::FunctionDecl>(
|
||||
context.clang_decls().Get(clang_decl_id).key.decl)
|
||||
: nullptr;
|
||||
}
|
||||
|
||||
auto IsCppOperatorMethod(Context& context, SemIR::InstId inst_id) -> bool {
|
||||
auto* function_decl = GetAsCppFunctionDecl(context, inst_id);
|
||||
return function_decl && IsCppOperatorMethodDecl(function_decl);
|
||||
}
|
||||
|
||||
auto IsCppConstructorOrNonMethodOperator(Context& context,
|
||||
SemIR::InstId inst_id) -> bool {
|
||||
auto* function_decl = GetAsCppFunctionDecl(context, inst_id);
|
||||
if (!function_decl) {
|
||||
return false;
|
||||
}
|
||||
if (isa<clang::CXXConstructorDecl>(function_decl)) {
|
||||
return true;
|
||||
}
|
||||
return !isa<clang::CXXMethodDecl>(function_decl) &&
|
||||
function_decl->isOverloadedOperator();
|
||||
}
|
||||
|
||||
} // namespace Carbon::Check
|
||||
|
||||
Reference in New Issue
Block a user