Skip to content

Commit 7572d55

Browse files
Add HasTypeQualifier, RemoveTypeQualifier & AddTypeQualifier
1 parent 3727acc commit 7572d55

File tree

3 files changed

+144
-0
lines changed

3 files changed

+144
-0
lines changed

include/CppInterOp/CppInterOp.h

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,18 @@ enum Operator : unsigned char {
9393

9494
enum OperatorArity : unsigned char { kUnary = 1, kBinary, kBoth };
9595

96+
/// Enum modelling CVR qualifiers.
97+
enum QualKind : unsigned char {
98+
Const = 1 << 0,
99+
Volatile = 1 << 1,
100+
Restrict = 1 << 2
101+
};
102+
103+
inline QualKind operator|(QualKind a, QualKind b) {
104+
return static_cast<QualKind>(static_cast<unsigned char>(a) |
105+
static_cast<unsigned char>(b));
106+
}
107+
96108
/// A class modeling function calls for functions produced by the interpreter
97109
/// in compiled code. It provides an information if we are calling a standard
98110
/// function, constructor or destructor.
@@ -263,6 +275,18 @@ CPPINTEROP_API bool IsEnumConstant(TCppScope_t handle);
263275
/// Checks if the passed value is an enum type or not.
264276
CPPINTEROP_API bool IsEnumType(TCppType_t type);
265277

278+
/// Checks if the passed type has qual Qualifiers
279+
/// qual can be ORed value of enum QualKind
280+
CPPINTEROP_API bool HasTypeQualifier(TCppType_t type, QualKind qual);
281+
282+
/// Returns type with the qual Qualifiers removed
283+
/// qual can be ORed value of enum QualKind
284+
CPPINTEROP_API TCppType_t RemoveTypeQualifier(TCppType_t type, QualKind qual);
285+
286+
/// Returns type with the qual Qualifiers added
287+
/// qual can be ORed value of enum QualKind
288+
CPPINTEROP_API TCppType_t AddTypeQualifier(TCppType_t type, QualKind qual);
289+
266290
/// Extracts enum declarations from a specified scope and stores them in
267291
/// vector
268292
CPPINTEROP_API void GetEnums(TCppScope_t scope,

lib/CppInterOp/CppInterOp.cpp

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1612,6 +1612,60 @@ TCppType_t GetCanonicalType(TCppType_t type) {
16121612
return QT.getCanonicalType().getAsOpaquePtr();
16131613
}
16141614

1615+
bool HasTypeQualifier(TCppType_t type, QualKind qual) {
1616+
if (!type)
1617+
return false;
1618+
1619+
QualType QT = QualType::getFromOpaquePtr(type);
1620+
if (qual & QualKind::Const) {
1621+
if (!QT.isConstQualified())
1622+
return false;
1623+
}
1624+
if (qual & QualKind::Volatile) {
1625+
if (!QT.isVolatileQualified())
1626+
return false;
1627+
}
1628+
if (qual & QualKind::Restrict) {
1629+
if (!QT.isRestrictQualified())
1630+
return false;
1631+
}
1632+
return true;
1633+
}
1634+
1635+
TCppType_t RemoveTypeQualifier(TCppType_t type, QualKind qual) {
1636+
if (!type)
1637+
return type;
1638+
1639+
auto QT = QualType(QualType::getFromOpaquePtr(type));
1640+
if (qual & QualKind::Const)
1641+
QT.removeLocalConst();
1642+
if (qual & QualKind::Volatile)
1643+
QT.removeLocalVolatile();
1644+
if (qual & QualKind::Restrict)
1645+
QT.removeLocalRestrict();
1646+
return QT.getAsOpaquePtr();
1647+
}
1648+
1649+
TCppType_t AddTypeQualifier(TCppType_t type, QualKind qual) {
1650+
if (!type)
1651+
return type;
1652+
1653+
auto QT = QualType(QualType::getFromOpaquePtr(type));
1654+
if (qual & QualKind::Const) {
1655+
if (!QT.isConstQualified())
1656+
QT.addConst();
1657+
}
1658+
if (qual & QualKind::Volatile) {
1659+
if (!QT.isVolatileQualified())
1660+
QT.addVolatile();
1661+
}
1662+
if (qual & QualKind::Restrict) {
1663+
if (!QT.isRestrictQualified())
1664+
QT.addRestrict();
1665+
}
1666+
return QT.getAsOpaquePtr();
1667+
}
1668+
16151669
// Internal functions that are not needed outside the library are
16161670
// encompassed in an anonymous namespace as follows. This function converts
16171671
// from a string to the actual type. It is used in the GetType() function.

unittests/CppInterOp/TypeReflectionTest.cpp

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -611,3 +611,69 @@ TEST(TypeReflectionTest, IsFunctionPointerType) {
611611
EXPECT_FALSE(
612612
Cpp::IsFunctionPointerType(Cpp::GetVariableType(Cpp::GetNamed("i"))));
613613
}
614+
615+
TEST(TypeReflectionTest, TypeQualifiers) {
616+
Cpp::CreateInterpreter();
617+
Cpp::Declare(R"(
618+
int *a;
619+
int *__restrict b;
620+
int *const c = 0;
621+
int *volatile d;
622+
int *const volatile e = nullptr;
623+
int *__restrict const f = nullptr;
624+
int *__restrict volatile g;
625+
int *__restrict const volatile h = nullptr;
626+
)");
627+
628+
Cpp::TCppType_t a = Cpp::GetVariableType(Cpp::GetNamed("a"));
629+
Cpp::TCppType_t b = Cpp::GetVariableType(Cpp::GetNamed("b"));
630+
Cpp::TCppType_t c = Cpp::GetVariableType(Cpp::GetNamed("c"));
631+
Cpp::TCppType_t d = Cpp::GetVariableType(Cpp::GetNamed("d"));
632+
Cpp::TCppType_t e = Cpp::GetVariableType(Cpp::GetNamed("e"));
633+
Cpp::TCppType_t f = Cpp::GetVariableType(Cpp::GetNamed("f"));
634+
Cpp::TCppType_t g = Cpp::GetVariableType(Cpp::GetNamed("g"));
635+
Cpp::TCppType_t h = Cpp::GetVariableType(Cpp::GetNamed("h"));
636+
637+
EXPECT_FALSE(Cpp::HasTypeQualifier(nullptr, Cpp::QualKind::Const));
638+
EXPECT_FALSE(Cpp::RemoveTypeQualifier(nullptr, Cpp::QualKind::Const));
639+
EXPECT_FALSE(Cpp::AddTypeQualifier(nullptr, Cpp::QualKind::Const));
640+
641+
EXPECT_FALSE(Cpp::HasTypeQualifier(a, Cpp::QualKind::Const));
642+
EXPECT_FALSE(Cpp::HasTypeQualifier(a, Cpp::QualKind::Volatile));
643+
EXPECT_FALSE(Cpp::HasTypeQualifier(a, Cpp::QualKind::Restrict));
644+
EXPECT_TRUE(Cpp::HasTypeQualifier(b, Cpp::QualKind::Restrict));
645+
EXPECT_TRUE(Cpp::HasTypeQualifier(c, Cpp::QualKind::Const));
646+
EXPECT_TRUE(Cpp::HasTypeQualifier(d, Cpp::QualKind::Volatile));
647+
EXPECT_TRUE(
648+
Cpp::HasTypeQualifier(e, Cpp::QualKind::Const | Cpp::QualKind::Volatile));
649+
EXPECT_TRUE(
650+
Cpp::HasTypeQualifier(f, Cpp::QualKind::Const | Cpp::QualKind::Restrict));
651+
EXPECT_TRUE(Cpp::HasTypeQualifier(g, Cpp::QualKind::Volatile |
652+
Cpp::QualKind::Restrict));
653+
EXPECT_TRUE(Cpp::HasTypeQualifier(h, Cpp::QualKind::Const |
654+
Cpp::QualKind::Volatile |
655+
Cpp::QualKind::Restrict));
656+
657+
EXPECT_EQ(a, Cpp::RemoveTypeQualifier(b, Cpp::QualKind::Restrict));
658+
EXPECT_EQ(a, Cpp::RemoveTypeQualifier(c, Cpp::QualKind::Const));
659+
EXPECT_EQ(a, Cpp::RemoveTypeQualifier(d, Cpp::QualKind::Volatile));
660+
EXPECT_EQ(a, Cpp::RemoveTypeQualifier(e, Cpp::QualKind::Const |
661+
Cpp::QualKind::Volatile));
662+
EXPECT_EQ(a, Cpp::RemoveTypeQualifier(f, Cpp::QualKind::Const |
663+
Cpp::QualKind::Restrict));
664+
EXPECT_EQ(a, Cpp::RemoveTypeQualifier(g, Cpp::QualKind::Volatile |
665+
Cpp::QualKind::Restrict));
666+
EXPECT_EQ(a, Cpp::RemoveTypeQualifier(h, Cpp::QualKind::Const |
667+
Cpp::QualKind::Volatile |
668+
Cpp::QualKind::Restrict));
669+
EXPECT_EQ(e, Cpp::RemoveTypeQualifier(h, Cpp::QualKind::Restrict));
670+
EXPECT_EQ(b, Cpp::RemoveTypeQualifier(h, Cpp::QualKind::Const |
671+
Cpp::QualKind::Volatile));
672+
673+
EXPECT_EQ(c, Cpp::AddTypeQualifier(a, Cpp::QualKind::Const));
674+
EXPECT_EQ(d, Cpp::AddTypeQualifier(a, Cpp::QualKind::Volatile));
675+
EXPECT_EQ(b, Cpp::AddTypeQualifier(a, Cpp::QualKind::Restrict));
676+
EXPECT_EQ(h, Cpp::AddTypeQualifier(a, Cpp::QualKind::Const |
677+
Cpp::QualKind::Volatile |
678+
Cpp::QualKind::Restrict));
679+
}

0 commit comments

Comments
 (0)