Skip to content

Commit 6e952e1

Browse files
Add HasTypeQualifier, RemoveTypeQualifier & AddTypeQualifier
1 parent f65f80a commit 6e952e1

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
@@ -94,6 +94,18 @@ enum Operator : unsigned char {
9494

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

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

324+
/// Checks if the passed type has qual Qualifiers
325+
/// qual can be ORed value of enum QualKind
326+
CPPINTEROP_API bool HasTypeQualifier(TCppType_t type, QualKind qual);
327+
328+
/// Returns type with the qual Qualifiers removed
329+
/// qual can be ORed value of enum QualKind
330+
CPPINTEROP_API TCppType_t RemoveTypeQualifier(TCppType_t type, QualKind qual);
331+
332+
/// Returns type with the qual Qualifiers added
333+
/// qual can be ORed value of enum QualKind
334+
CPPINTEROP_API TCppType_t AddTypeQualifier(TCppType_t type, QualKind qual);
335+
312336
/// Extracts enum declarations from a specified scope and stores them in
313337
/// vector
314338
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
@@ -1700,6 +1700,60 @@ TCppType_t GetCanonicalType(TCppType_t type) {
17001700
return QT.getCanonicalType().getAsOpaquePtr();
17011701
}
17021702

1703+
bool HasTypeQualifier(TCppType_t type, QualKind qual) {
1704+
if (!type)
1705+
return false;
1706+
1707+
QualType QT = QualType::getFromOpaquePtr(type);
1708+
if (qual & QualKind::Const) {
1709+
if (!QT.isConstQualified())
1710+
return false;
1711+
}
1712+
if (qual & QualKind::Volatile) {
1713+
if (!QT.isVolatileQualified())
1714+
return false;
1715+
}
1716+
if (qual & QualKind::Restrict) {
1717+
if (!QT.isRestrictQualified())
1718+
return false;
1719+
}
1720+
return true;
1721+
}
1722+
1723+
TCppType_t RemoveTypeQualifier(TCppType_t type, QualKind qual) {
1724+
if (!type)
1725+
return type;
1726+
1727+
auto QT = QualType(QualType::getFromOpaquePtr(type));
1728+
if (qual & QualKind::Const)
1729+
QT.removeLocalConst();
1730+
if (qual & QualKind::Volatile)
1731+
QT.removeLocalVolatile();
1732+
if (qual & QualKind::Restrict)
1733+
QT.removeLocalRestrict();
1734+
return QT.getAsOpaquePtr();
1735+
}
1736+
1737+
TCppType_t AddTypeQualifier(TCppType_t type, QualKind qual) {
1738+
if (!type)
1739+
return type;
1740+
1741+
auto QT = QualType(QualType::getFromOpaquePtr(type));
1742+
if (qual & QualKind::Const) {
1743+
if (!QT.isConstQualified())
1744+
QT.addConst();
1745+
}
1746+
if (qual & QualKind::Volatile) {
1747+
if (!QT.isVolatileQualified())
1748+
QT.addVolatile();
1749+
}
1750+
if (qual & QualKind::Restrict) {
1751+
if (!QT.isRestrictQualified())
1752+
QT.addRestrict();
1753+
}
1754+
return QT.getAsOpaquePtr();
1755+
}
1756+
17031757
// Internal functions that are not needed outside the library are
17041758
// encompassed in an anonymous namespace as follows. This function converts
17051759
// 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
@@ -620,3 +620,69 @@ TEST(TypeReflectionTest, OperatorSpelling) {
620620
EXPECT_EQ(Cpp::GetOperatorFromSpelling("()"), Cpp::OP_Call);
621621
EXPECT_EQ(Cpp::GetOperatorFromSpelling("invalid"), Cpp::OP_None);
622622
}
623+
624+
TEST(TypeReflectionTest, TypeQualifiers) {
625+
Cpp::CreateInterpreter();
626+
Cpp::Declare(R"(
627+
int *a;
628+
int *__restrict__ b;
629+
int *const c = 0;
630+
int *volatile d;
631+
int *const volatile e = nullptr;
632+
int *__restrict__ const f = nullptr;
633+
int *__restrict__ volatile g;
634+
int *__restrict__ const volatile h = nullptr;
635+
)");
636+
637+
Cpp::TCppType_t a = Cpp::GetVariableType(Cpp::GetNamed("a"));
638+
Cpp::TCppType_t b = Cpp::GetVariableType(Cpp::GetNamed("b"));
639+
Cpp::TCppType_t c = Cpp::GetVariableType(Cpp::GetNamed("c"));
640+
Cpp::TCppType_t d = Cpp::GetVariableType(Cpp::GetNamed("d"));
641+
Cpp::TCppType_t e = Cpp::GetVariableType(Cpp::GetNamed("e"));
642+
Cpp::TCppType_t f = Cpp::GetVariableType(Cpp::GetNamed("f"));
643+
Cpp::TCppType_t g = Cpp::GetVariableType(Cpp::GetNamed("g"));
644+
Cpp::TCppType_t h = Cpp::GetVariableType(Cpp::GetNamed("h"));
645+
646+
EXPECT_FALSE(Cpp::HasTypeQualifier(nullptr, Cpp::QualKind::Const));
647+
EXPECT_FALSE(Cpp::RemoveTypeQualifier(nullptr, Cpp::QualKind::Const));
648+
EXPECT_FALSE(Cpp::AddTypeQualifier(nullptr, Cpp::QualKind::Const));
649+
650+
EXPECT_FALSE(Cpp::HasTypeQualifier(a, Cpp::QualKind::Const));
651+
EXPECT_FALSE(Cpp::HasTypeQualifier(a, Cpp::QualKind::Volatile));
652+
EXPECT_FALSE(Cpp::HasTypeQualifier(a, Cpp::QualKind::Restrict));
653+
EXPECT_TRUE(Cpp::HasTypeQualifier(b, Cpp::QualKind::Restrict));
654+
EXPECT_TRUE(Cpp::HasTypeQualifier(c, Cpp::QualKind::Const));
655+
EXPECT_TRUE(Cpp::HasTypeQualifier(d, Cpp::QualKind::Volatile));
656+
EXPECT_TRUE(
657+
Cpp::HasTypeQualifier(e, Cpp::QualKind::Const | Cpp::QualKind::Volatile));
658+
EXPECT_TRUE(
659+
Cpp::HasTypeQualifier(f, Cpp::QualKind::Const | Cpp::QualKind::Restrict));
660+
EXPECT_TRUE(Cpp::HasTypeQualifier(g, Cpp::QualKind::Volatile |
661+
Cpp::QualKind::Restrict));
662+
EXPECT_TRUE(Cpp::HasTypeQualifier(h, Cpp::QualKind::Const |
663+
Cpp::QualKind::Volatile |
664+
Cpp::QualKind::Restrict));
665+
666+
EXPECT_EQ(a, Cpp::RemoveTypeQualifier(b, Cpp::QualKind::Restrict));
667+
EXPECT_EQ(a, Cpp::RemoveTypeQualifier(c, Cpp::QualKind::Const));
668+
EXPECT_EQ(a, Cpp::RemoveTypeQualifier(d, Cpp::QualKind::Volatile));
669+
EXPECT_EQ(a, Cpp::RemoveTypeQualifier(e, Cpp::QualKind::Const |
670+
Cpp::QualKind::Volatile));
671+
EXPECT_EQ(a, Cpp::RemoveTypeQualifier(f, Cpp::QualKind::Const |
672+
Cpp::QualKind::Restrict));
673+
EXPECT_EQ(a, Cpp::RemoveTypeQualifier(g, Cpp::QualKind::Volatile |
674+
Cpp::QualKind::Restrict));
675+
EXPECT_EQ(a, Cpp::RemoveTypeQualifier(h, Cpp::QualKind::Const |
676+
Cpp::QualKind::Volatile |
677+
Cpp::QualKind::Restrict));
678+
EXPECT_EQ(e, Cpp::RemoveTypeQualifier(h, Cpp::QualKind::Restrict));
679+
EXPECT_EQ(b, Cpp::RemoveTypeQualifier(h, Cpp::QualKind::Const |
680+
Cpp::QualKind::Volatile));
681+
682+
EXPECT_EQ(c, Cpp::AddTypeQualifier(a, Cpp::QualKind::Const));
683+
EXPECT_EQ(d, Cpp::AddTypeQualifier(a, Cpp::QualKind::Volatile));
684+
EXPECT_EQ(b, Cpp::AddTypeQualifier(a, Cpp::QualKind::Restrict));
685+
EXPECT_EQ(h, Cpp::AddTypeQualifier(a, Cpp::QualKind::Const |
686+
Cpp::QualKind::Volatile |
687+
Cpp::QualKind::Restrict));
688+
}

0 commit comments

Comments
 (0)