mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-10-04 17:51:05 +01:00
Support LP64 platforms such as Darwin where int64_t is long long. (#7596)
Add `Core.CppCompat.[U]Long64` to represent a 64-bit long that is not `i64`. Treat it as being "just slightly smaller than" `i64`, like we treat `Core.CppCompat.LongLong64` as being "just slightly larger than" `i64`, so that we get implicit conversions `Cpp.long` -> `i64` -> `Cpp.long_long` on all targets. This follows the direction of proposal #5448, and seems like the obvious extension of the `[U]Long32` and `[U]LongLong64` types added in #6275 for targets of this "shape". Assisted-by: Gemini via Antigravity
This commit is contained in:
@@ -15,6 +15,7 @@
|
||||
#include "clang/AST/RecordLayout.h"
|
||||
#include "clang/AST/UnresolvedSet.h"
|
||||
#include "clang/AST/VTableBuilder.h"
|
||||
#include "clang/Basic/TargetInfo.h"
|
||||
#include "clang/Frontend/CompilerInvocation.h"
|
||||
#include "clang/Lex/MacroInfo.h"
|
||||
#include "clang/Lex/Preprocessor.h"
|
||||
@@ -1109,17 +1110,48 @@ static auto MakeCppCompatType(Context& context, SemIR::LocId loc_id,
|
||||
LookupNameInCore(context, loc_id, {CoreIdentifier::CppCompat, name}));
|
||||
}
|
||||
|
||||
// Maps a C++ builtin integer type to a Carbon `Core.CppCompat` type.
|
||||
static auto MapBuiltinCppCompatIntegerType(Context& context,
|
||||
unsigned int cpp_width,
|
||||
unsigned int carbon_width,
|
||||
CoreIdentifier cpp_compat_name)
|
||||
-> TypeExpr {
|
||||
if (cpp_width != carbon_width) {
|
||||
return TypeExpr::None;
|
||||
auto GetIntNType(const clang::ASTContext& ast_context, unsigned width,
|
||||
bool is_signed) -> clang::QualType {
|
||||
const auto& target_info = ast_context.getTargetInfo();
|
||||
|
||||
// Work around Clang's getIntTypeForBitwidth being broken in various targets.
|
||||
auto target_type = clang::TargetInfo::IntType::NoInt;
|
||||
if (width == 64) {
|
||||
target_type =
|
||||
is_signed ? target_info.getInt64Type() : target_info.getUInt64Type();
|
||||
} else if (width == 16) {
|
||||
target_type =
|
||||
is_signed ? target_info.getInt16Type() : target_info.getUInt16Type();
|
||||
} else {
|
||||
target_type = target_info.getIntTypeByWidth(width, is_signed);
|
||||
}
|
||||
|
||||
return MakeCppCompatType(context, Parse::NodeId::None, cpp_compat_name);
|
||||
switch (target_type) {
|
||||
case clang::TargetInfo::NoInt:
|
||||
// Call getIntTypeForBitwidth to pick up its i128 handling.
|
||||
return ast_context.getIntTypeForBitwidth(width, is_signed);
|
||||
|
||||
case clang::TargetInfo::SignedChar:
|
||||
return ast_context.SignedCharTy;
|
||||
case clang::TargetInfo::UnsignedChar:
|
||||
return ast_context.UnsignedCharTy;
|
||||
case clang::TargetInfo::SignedShort:
|
||||
return ast_context.ShortTy;
|
||||
case clang::TargetInfo::UnsignedShort:
|
||||
return ast_context.UnsignedShortTy;
|
||||
case clang::TargetInfo::SignedInt:
|
||||
return ast_context.IntTy;
|
||||
case clang::TargetInfo::UnsignedInt:
|
||||
return ast_context.UnsignedIntTy;
|
||||
case clang::TargetInfo::SignedLong:
|
||||
return ast_context.LongTy;
|
||||
case clang::TargetInfo::UnsignedLong:
|
||||
return ast_context.UnsignedLongTy;
|
||||
case clang::TargetInfo::SignedLongLong:
|
||||
return ast_context.LongLongTy;
|
||||
case clang::TargetInfo::UnsignedLongLong:
|
||||
return ast_context.UnsignedLongLongTy;
|
||||
}
|
||||
}
|
||||
|
||||
// Maps a C++ builtin integer type to a Carbon type.
|
||||
@@ -1130,7 +1162,10 @@ static auto MapBuiltinIntegerType(Context& context, SemIR::LocId loc_id,
|
||||
clang::ASTContext& ast_context = context.ast_context();
|
||||
unsigned width = ast_context.getIntWidth(qual_type);
|
||||
bool is_signed = type.isSignedInteger();
|
||||
auto int_n_type = ast_context.getIntTypeForBitwidth(width, is_signed);
|
||||
|
||||
// Check whether the type is `intN_t` or `uintN_t`, and if so, map it to `iN`
|
||||
// or `uN` respectively.
|
||||
auto int_n_type = GetIntNType(ast_context, width, is_signed);
|
||||
if (clang::ASTContext::hasSameType(qual_type, int_n_type)) {
|
||||
TypeExpr type_expr =
|
||||
MakeIntType(context, context.ints().Add(width), is_signed);
|
||||
@@ -1144,26 +1179,41 @@ static auto MapBuiltinIntegerType(Context& context, SemIR::LocId loc_id,
|
||||
}
|
||||
return type_expr;
|
||||
}
|
||||
if (clang::ASTContext::hasSameType(qual_type, ast_context.CharTy)) {
|
||||
return ExprAsType(context, Parse::NodeId::None,
|
||||
MakeCharTypeLiteral(context, Parse::NodeId::None));
|
||||
}
|
||||
if (clang::ASTContext::hasSameType(qual_type, ast_context.LongTy)) {
|
||||
return MapBuiltinCppCompatIntegerType(context, width, 32,
|
||||
CoreIdentifier::Long32);
|
||||
}
|
||||
if (clang::ASTContext::hasSameType(qual_type, ast_context.UnsignedLongTy)) {
|
||||
return MapBuiltinCppCompatIntegerType(context, width, 32,
|
||||
CoreIdentifier::ULong32);
|
||||
}
|
||||
if (clang::ASTContext::hasSameType(qual_type, ast_context.LongLongTy)) {
|
||||
return MapBuiltinCppCompatIntegerType(context, width, 64,
|
||||
CoreIdentifier::LongLong64);
|
||||
}
|
||||
if (clang::ASTContext::hasSameType(qual_type,
|
||||
ast_context.UnsignedLongLongTy)) {
|
||||
return MapBuiltinCppCompatIntegerType(context, width, 64,
|
||||
CoreIdentifier::ULongLong64);
|
||||
|
||||
// Handle special cases for types that don't map to `iN` or `uN`.
|
||||
switch (type.getKind()) {
|
||||
case clang::BuiltinType::Char_S:
|
||||
case clang::BuiltinType::Char_U:
|
||||
return ExprAsType(context, Parse::NodeId::None,
|
||||
MakeCharTypeLiteral(context, Parse::NodeId::None));
|
||||
case clang::BuiltinType::Long:
|
||||
if (width == 32) {
|
||||
return MakeCppCompatType(context, loc_id, CoreIdentifier::Long32);
|
||||
}
|
||||
if (width == 64) {
|
||||
return MakeCppCompatType(context, loc_id, CoreIdentifier::Long64);
|
||||
}
|
||||
break;
|
||||
case clang::BuiltinType::ULong:
|
||||
if (width == 32) {
|
||||
return MakeCppCompatType(context, loc_id, CoreIdentifier::ULong32);
|
||||
}
|
||||
if (width == 64) {
|
||||
return MakeCppCompatType(context, loc_id, CoreIdentifier::ULong64);
|
||||
}
|
||||
break;
|
||||
case clang::BuiltinType::LongLong:
|
||||
if (width == 64) {
|
||||
return MakeCppCompatType(context, loc_id, CoreIdentifier::LongLong64);
|
||||
}
|
||||
break;
|
||||
case clang::BuiltinType::ULongLong:
|
||||
if (width == 64) {
|
||||
return MakeCppCompatType(context, loc_id, CoreIdentifier::ULongLong64);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return TypeExpr::None;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user