Skip to content

Commit bc734bb

Browse files
authored
C++ Interop: Add Core.CppCompat.Long32 as a distinct type for Cpp.long when long is 32 bits (#6364)
For now, only support implicit conversions from and to `i32`. See #6275 for rationale. Part of #5263.
1 parent e62678e commit bc734bb

File tree

7 files changed

+368
-123
lines changed

7 files changed

+368
-123
lines changed

core/prelude/types.carbon

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ package Core library "prelude/types";
66

77
export import library "prelude/types/bool";
88
export import library "prelude/types/char";
9+
export import library "prelude/types/cpp/int";
910
export import library "prelude/types/float";
1011
export import library "prelude/types/float_literal";
1112
export import library "prelude/types/int";

core/prelude/types/cpp/int.carbon

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
// Part of the Carbon Language project, under the Apache License v2.0 with LLVM
2+
// Exceptions. See /LICENSE for license information.
3+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
4+
5+
package Core library "prelude/types/cpp/int";
6+
7+
import library "prelude/operators";
8+
import library "prelude/types/int";
9+
import library "prelude/types/int_literal";
10+
11+
namespace CppCompat;
12+
13+
// TODO: Add ULong32, LongLong64, ULongLong64.
14+
class CppCompat.Long32 {
15+
adapt i32;
16+
}
17+
18+
// TODO: Copy.
19+
20+
// Conversions.
21+
22+
// TODO: ImplicitAs from IntLiteral to Long32.
23+
// TODO: ImplicitAs from Long32 to IntLiteral.
24+
25+
// TODO: ImplicitAs from Int(N) to Long32 if N < 32.
26+
impl i32 as ImplicitAs(CppCompat.Long32) {
27+
fn Convert[self: Self]() -> CppCompat.Long32 = "int.convert_checked";
28+
}
29+
30+
// TODO: ImplicitAs from Long32 to Int(N) if N > 32.
31+
final impl CppCompat.Long32 as ImplicitAs(i32) {
32+
fn Convert[self: Self]() -> i32 = "int.convert";
33+
}
34+
35+
// TODO: As from Long32 to Int(N) if N < 32.
36+
// TODO: As from Int(N) to Long32 if N > 32.
37+
38+
// TODO: Operations on Long32.

toolchain/check/cpp/import.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1112,6 +1112,11 @@ static auto MapBuiltinIntegerType(Context& context, SemIR::LocId loc_id,
11121112
return ExprAsType(context, Parse::NodeId::None,
11131113
MakeCharTypeLiteral(context, Parse::NodeId::None));
11141114
}
1115+
if (ast_context.hasSameType(qual_type, ast_context.LongTy) && width == 32) {
1116+
return ExprAsType(context, Parse::NodeId::None,
1117+
LookupNameInCore(context, Parse::NodeId::None,
1118+
{"CppCompat", "Long32"}));
1119+
}
11151120
return TypeExpr::None;
11161121
}
11171122

toolchain/check/cpp/type_mapping.cpp

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,8 @@ static auto LookupCppType(
104104
// type is not supported.
105105
static auto TryMapClassType(Context& context, SemIR::ClassType class_type)
106106
-> clang::QualType {
107+
clang::ASTContext& ast_context = context.ast_context();
108+
107109
// If the class was imported from C++, return the original C++ type.
108110
auto clang_decl_id =
109111
context.name_scopes()
@@ -112,7 +114,7 @@ static auto TryMapClassType(Context& context, SemIR::ClassType class_type)
112114
if (clang_decl_id.has_value()) {
113115
clang::Decl* clang_decl = context.clang_decls().Get(clang_decl_id).key.decl;
114116
auto* tag_type_decl = clang::cast<clang::TagDecl>(clang_decl);
115-
return context.ast_context().getCanonicalTagType(tag_type_decl);
117+
return ast_context.getCanonicalTagType(tag_type_decl);
116118
}
117119

118120
// If the class represents a Carbon type literal, map it to the corresponding
@@ -135,22 +137,28 @@ static auto TryMapClassType(Context& context, SemIR::ClassType class_type)
135137
CARBON_FATAL("Unexpected invalid numeric type literal");
136138
}
137139
case SemIR::NumericTypeLiteralInfo::Float: {
138-
return context.ast_context().getRealTypeForBitwidth(
140+
return ast_context.getRealTypeForBitwidth(
139141
bit_width, clang::FloatModeKind::NoFloat);
140142
}
141143
case SemIR::NumericTypeLiteralInfo::Int: {
142-
return context.ast_context().getIntTypeForBitwidth(bit_width, true);
144+
return ast_context.getIntTypeForBitwidth(bit_width, true);
143145
}
144146
case SemIR::NumericTypeLiteralInfo::UInt: {
145-
return context.ast_context().getIntTypeForBitwidth(bit_width, false);
147+
return ast_context.getIntTypeForBitwidth(bit_width, false);
146148
}
147149
}
148150
}
149151
case SemIR::TypeLiteralInfo::Char: {
150-
return context.ast_context().CharTy;
152+
return ast_context.CharTy;
153+
}
154+
case SemIR::TypeLiteralInfo::CppLong32: {
155+
if (ast_context.getIntWidth(ast_context.LongTy) == 32) {
156+
return ast_context.LongTy;
157+
}
158+
break;
151159
}
152160
case SemIR::TypeLiteralInfo::CppNullptrT: {
153-
return context.ast_context().NullPtrTy;
161+
return ast_context.NullPtrTy;
154162
}
155163
case SemIR::TypeLiteralInfo::Str: {
156164
return LookupCppType(context, {"std", "string_view"});

0 commit comments

Comments
 (0)