From 653a6bbe53c158154c955022df12d7f4a25390f4 Mon Sep 17 00:00:00 2001 From: Iv-F Date: Wed, 13 May 2026 14:37:41 +0300 Subject: [PATCH] Add type qualifier transforms and type factory functions --- lib/CppInterOp/CppInterOp.cpp | 79 +++++++++++++++ lib/CppInterOp/CppInterOp.td | 16 +++ unittests/CppInterOp/TypeReflectionTest.cpp | 103 ++++++++++++++++++++ 3 files changed, 198 insertions(+) diff --git a/lib/CppInterOp/CppInterOp.cpp b/lib/CppInterOp/CppInterOp.cpp index b00684a19..745211a0c 100644 --- a/lib/CppInterOp/CppInterOp.cpp +++ b/lib/CppInterOp/CppInterOp.cpp @@ -2401,6 +2401,85 @@ TCppType_t GetUnderlyingType(TCppType_t type) { return INTEROP_RETURN(QT.getAsOpaquePtr()); } +TCppType_t GetSignedType(TCppType_t type) { + INTEROP_TRACE(type); + if (!type) + return INTEROP_RETURN(nullptr); + QualType QT = QualType::getFromOpaquePtr(type); + const BuiltinType *BT = QT->getAs(); + if (!BT) + return INTEROP_RETURN(QT.getAsOpaquePtr()); + ASTContext &C = getSema().getASTContext(); + QualType SignedQT; + switch (BT->getKind()) { + case BuiltinType::SChar: + case BuiltinType::Short: + case BuiltinType::Int: + case BuiltinType::Long: + case BuiltinType::LongLong: + case BuiltinType::Int128: + return INTEROP_RETURN(QT.getAsOpaquePtr()); + case BuiltinType::UChar: + case BuiltinType::Char_U: + SignedQT = C.SignedCharTy; break; + case BuiltinType::UShort: + SignedQT = C.ShortTy; break; + case BuiltinType::UInt: + SignedQT = C.IntTy; break; + case BuiltinType::ULong: + SignedQT = C.LongTy; break; + case BuiltinType::ULongLong: + SignedQT = C.LongLongTy; break; + case BuiltinType::UInt128: + SignedQT = C.Int128Ty; break; + case BuiltinType::Char_S: + return INTEROP_RETURN(QT.getAsOpaquePtr()); + default: + return INTEROP_RETURN(QT.getAsOpaquePtr()); + } + SignedQT = C.getQualifiedType(SignedQT, QT.getQualifiers()); + return INTEROP_RETURN(SignedQT.getAsOpaquePtr()); +} + +TCppType_t GetUnsignedType(TCppType_t type) { + INTEROP_TRACE(type); + if (!type) + return INTEROP_RETURN(nullptr); + QualType QT = QualType::getFromOpaquePtr(type); + const BuiltinType *BT = QT->getAs(); + if (!BT) + return INTEROP_RETURN(QT.getAsOpaquePtr()); + ASTContext &C = getSema().getASTContext(); + QualType UnsignedQT; + switch (BT->getKind()) { + case BuiltinType::UChar: + case BuiltinType::Char_U: + case BuiltinType::UShort: + case BuiltinType::UInt: + case BuiltinType::ULong: + case BuiltinType::ULongLong: + case BuiltinType::UInt128: + return INTEROP_RETURN(QT.getAsOpaquePtr()); + case BuiltinType::SChar: + case BuiltinType::Char_S: + UnsignedQT = C.UnsignedCharTy; break; + case BuiltinType::Short: + UnsignedQT = C.UnsignedShortTy; break; + case BuiltinType::Int: + UnsignedQT = C.UnsignedIntTy; break; + case BuiltinType::Long: + UnsignedQT = C.UnsignedLongTy; break; + case BuiltinType::LongLong: + UnsignedQT = C.UnsignedLongLongTy; break; + case BuiltinType::Int128: + UnsignedQT = C.UnsignedInt128Ty; break; + default: + return INTEROP_RETURN(QT.getAsOpaquePtr()); + } + UnsignedQT = C.getQualifiedType(UnsignedQT, QT.getQualifiers()); + return INTEROP_RETURN(UnsignedQT.getAsOpaquePtr()); +} + std::string GetTypeAsString(TCppType_t var) { INTEROP_TRACE(var); QualType QT = QualType::getFromOpaquePtr(var); diff --git a/lib/CppInterOp/CppInterOp.td b/lib/CppInterOp/CppInterOp.td index d3958325e..d00dc288e 100644 --- a/lib/CppInterOp/CppInterOp.td +++ b/lib/CppInterOp/CppInterOp.td @@ -396,6 +396,22 @@ def GetUnderlyingType : CppInterOpAPI { ]; } +def GetSignedType : CppInterOpAPI { + let Doc = "Gets the signed counterpart of an integral type. Returns the type unchanged if it has no signed counterpart."; + let ReturnType = "TCppType_t"; + let Args = [ + Arg<"TCppType_t", "type"> + ]; +} + +def GetUnsignedType : CppInterOpAPI { + let Doc = "Gets the unsigned counterpart of an integral type. Returns the type unchanged if it has no unsigned counterpart."; + let ReturnType = "TCppType_t"; + let Args = [ + Arg<"TCppType_t", "type"> + ]; +} + def IsRecordType : CppInterOpAPI { let Doc = "Checks if the provided parameter is a Record (struct)."; diff --git a/unittests/CppInterOp/TypeReflectionTest.cpp b/unittests/CppInterOp/TypeReflectionTest.cpp index 6df0a6c6f..4c215f37c 100644 --- a/unittests/CppInterOp/TypeReflectionTest.cpp +++ b/unittests/CppInterOp/TypeReflectionTest.cpp @@ -389,6 +389,109 @@ TYPED_TEST(CPPINTEROP_TEST_MODE, TypeReflection_IsUnderlyingTypeRecordType) { EXPECT_TRUE(is_var_of_underly_record_ty(Decls[24])); } +TYPED_TEST(CPPINTEROP_TEST_MODE, TypeReflection_GetSignedType) { + std::vector Decls; + std::string code = R"( + unsigned char var0 = 0; + unsigned short var1 = 0; + unsigned int var2 = 0; + unsigned long var3 = 0; + unsigned long long var4 = 0; + unsigned __int128 var5 = 0; + int var6 = 0; + short var7 = 0; + long var8 = 0; + long long var9 = 0; + __int128 var10 = 0; + float var11 = 0.0f; + signed char var12 = 0; + char var13 = 0; + struct MyStruct {} var14; + )"; + GetAllTopLevelDecls(code, Decls); + EXPECT_EQ(Cpp::GetTypeAsString( + Cpp::GetSignedType(Cpp::GetVariableType(Decls[0]))), "signed char"); + EXPECT_EQ(Cpp::GetTypeAsString( + Cpp::GetSignedType(Cpp::GetVariableType(Decls[1]))), "short"); + EXPECT_EQ(Cpp::GetTypeAsString( + Cpp::GetSignedType(Cpp::GetVariableType(Decls[2]))), "int"); + EXPECT_EQ(Cpp::GetTypeAsString( + Cpp::GetSignedType(Cpp::GetVariableType(Decls[3]))), "long"); + EXPECT_EQ(Cpp::GetTypeAsString( + Cpp::GetSignedType(Cpp::GetVariableType(Decls[4]))), "long long"); + EXPECT_EQ(Cpp::GetTypeAsString( + Cpp::GetSignedType(Cpp::GetVariableType(Decls[5]))), "__int128"); + EXPECT_EQ(Cpp::GetTypeAsString( + Cpp::GetSignedType(Cpp::GetVariableType(Decls[6]))), "int"); + EXPECT_EQ(Cpp::GetTypeAsString( + Cpp::GetSignedType(Cpp::GetVariableType(Decls[7]))), "short"); + EXPECT_EQ(Cpp::GetTypeAsString( + Cpp::GetSignedType(Cpp::GetVariableType(Decls[8]))), "long"); + EXPECT_EQ(Cpp::GetTypeAsString( + Cpp::GetSignedType(Cpp::GetVariableType(Decls[9]))), "long long"); + EXPECT_EQ(Cpp::GetTypeAsString( + Cpp::GetSignedType(Cpp::GetVariableType(Decls[10]))), "__int128"); + EXPECT_EQ(Cpp::GetTypeAsString( + Cpp::GetSignedType(Cpp::GetVariableType(Decls[11]))), "float"); + EXPECT_EQ(Cpp::GetTypeAsString( + Cpp::GetSignedType(Cpp::GetVariableType(Decls[12]))), "signed char"); + EXPECT_EQ(Cpp::GetTypeAsString( + Cpp::GetSignedType(Cpp::GetVariableType(Decls[13]))), "char"); + EXPECT_EQ(Cpp::GetTypeAsString( + Cpp::GetSignedType(Cpp::GetVariableType(Decls[15]))), "MyStruct"); + EXPECT_EQ(Cpp::GetSignedType(nullptr), nullptr); +} + +TYPED_TEST(CPPINTEROP_TEST_MODE, TypeReflection_GetUnsignedType) { + std::vector Decls; + std::string code = R"( + signed char var0 = 0; + short var1 = 0; + int var2 = 0; + long var3 = 0; + long long var4 = 0; + __int128 var5 = 0; + unsigned char var6 = 0; + unsigned short var7 = 0; + unsigned int var8 = 0; + unsigned long var9 = 0; + unsigned long long var10 = 0; + unsigned __int128 var11 = 0; + float var12 = 0.0f; + struct MyStruct {} var13; + )"; + GetAllTopLevelDecls(code, Decls); + EXPECT_EQ(Cpp::GetTypeAsString( + Cpp::GetUnsignedType(Cpp::GetVariableType(Decls[0]))), "unsigned char"); + EXPECT_EQ(Cpp::GetTypeAsString( + Cpp::GetUnsignedType(Cpp::GetVariableType(Decls[1]))), "unsigned short"); + EXPECT_EQ(Cpp::GetTypeAsString( + Cpp::GetUnsignedType(Cpp::GetVariableType(Decls[2]))), "unsigned int"); + EXPECT_EQ(Cpp::GetTypeAsString( + Cpp::GetUnsignedType(Cpp::GetVariableType(Decls[3]))), "unsigned long"); + EXPECT_EQ(Cpp::GetTypeAsString( + Cpp::GetUnsignedType(Cpp::GetVariableType(Decls[4]))), "unsigned long long"); + EXPECT_EQ(Cpp::GetTypeAsString( + Cpp::GetUnsignedType(Cpp::GetVariableType(Decls[5]))), "unsigned __int128"); + EXPECT_EQ(Cpp::GetTypeAsString( + Cpp::GetUnsignedType(Cpp::GetVariableType(Decls[6]))), "unsigned char"); + EXPECT_EQ(Cpp::GetTypeAsString( + Cpp::GetUnsignedType(Cpp::GetVariableType(Decls[7]))), "unsigned short"); + EXPECT_EQ(Cpp::GetTypeAsString( + Cpp::GetUnsignedType(Cpp::GetVariableType(Decls[8]))), "unsigned int"); + EXPECT_EQ(Cpp::GetTypeAsString( + Cpp::GetUnsignedType(Cpp::GetVariableType(Decls[9]))), "unsigned long"); + EXPECT_EQ(Cpp::GetTypeAsString( + Cpp::GetUnsignedType(Cpp::GetVariableType(Decls[10]))), "unsigned long long"); + EXPECT_EQ(Cpp::GetTypeAsString( + Cpp::GetUnsignedType(Cpp::GetVariableType(Decls[11]))), "unsigned __int128"); + EXPECT_EQ(Cpp::GetTypeAsString( + Cpp::GetUnsignedType(Cpp::GetVariableType(Decls[12]))), "float"); + EXPECT_EQ(Cpp::GetTypeAsString( + Cpp::GetUnsignedType(Cpp::GetVariableType(Decls[14]))), "MyStruct"); + EXPECT_EQ(Cpp::GetUnsignedType(nullptr), nullptr); +} + TYPED_TEST(CPPINTEROP_TEST_MODE, TypeReflection_GetComplexType) { TestFixture::CreateInterpreter();