Skip to content

Commit e175719

Browse files
Add HasTypeQualifier and RemoveTypeQualifier
1 parent fa1c97d commit e175719

File tree

3 files changed

+106
-0
lines changed

3 files changed

+106
-0
lines changed

include/clang/Interpreter/CppInterOp.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,12 @@ namespace Cpp {
8888

8989
enum OperatorArity { kUnary = 1, kBinary, kBoth };
9090

91+
enum Qualifier : unsigned {
92+
Const = 0b01,
93+
Volatile = 0b010,
94+
Restrict = 0b0100
95+
};
96+
9197
/// A class modeling function calls for functions produced by the interpreter
9298
/// in compiled code. It provides an information if we are calling a standard
9399
/// function, constructor or destructor.
@@ -253,6 +259,14 @@ namespace Cpp {
253259
/// Checks if the passed value is an enum type or not.
254260
CPPINTEROP_API bool IsEnumType(TCppType_t type);
255261

262+
/// Checks if the passed type has qual Qualifiers
263+
/// qual can be ORed value of enum Qualifier
264+
CPPINTEROP_API bool HasTypeQualifier(TCppType_t type, unsigned qual);
265+
266+
/// Returns type with the qual Qualifiers
267+
/// qual can be ORed value of enum Qualifier
268+
CPPINTEROP_API TCppType_t RemoveTypeQualifier(TCppType_t type, unsigned qual);
269+
256270
/// Extracts enum declarations from a specified scope and stores them in
257271
/// vector
258272
CPPINTEROP_API void GetEnums(TCppScope_t scope,

lib/Interpreter/CppInterOp.cpp

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1657,6 +1657,40 @@ namespace Cpp {
16571657
return QT.getCanonicalType().getAsOpaquePtr();
16581658
}
16591659

1660+
bool HasTypeQualifier(TCppType_t type, unsigned qual) {
1661+
if (!type)
1662+
return false;
1663+
1664+
QualType QT = QualType::getFromOpaquePtr(type);
1665+
if (qual & Qualifier::Const) {
1666+
if (!QT.isConstQualified())
1667+
return false;
1668+
}
1669+
if (qual & Qualifier::Volatile) {
1670+
if (!QT.isVolatileQualified())
1671+
return false;
1672+
}
1673+
if (qual & Qualifier::Restrict) {
1674+
if (!QT.isRestrictQualified())
1675+
return false;
1676+
}
1677+
return true;
1678+
}
1679+
1680+
TCppType_t RemoveTypeQualifier(TCppType_t type, unsigned qual) {
1681+
if (!type)
1682+
return type;
1683+
1684+
auto QT = QualType(QualType::getFromOpaquePtr(type));
1685+
if (qual & Qualifier::Const)
1686+
QT.removeLocalConst();
1687+
if (qual & Qualifier::Volatile)
1688+
QT.removeLocalVolatile();
1689+
if (qual & Qualifier::Restrict)
1690+
QT.removeLocalRestrict();
1691+
return QT.getAsOpaquePtr();
1692+
}
1693+
16601694
// Internal functions that are not needed outside the library are
16611695
// encompassed in an anonymous namespace as follows. This function converts
16621696
// from a string to the actual type. It is used in the GetType() function.

unittests/CppInterOp/TypeReflectionTest.cpp

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

0 commit comments

Comments
 (0)