Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 32 additions & 7 deletions include/CppInterOp/CppInterOp.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,19 @@ using TCppFuncAddr_t = void*;
using TInterp_t = void*;
using TCppObject_t = void*;

enum Operator : unsigned char {
template <typename T> struct TruthValue {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suspect we can forward declare the operators and implement them in the cpp file and then we could hide this class completely from the interface.

T t;
constexpr TruthValue(T t) : t(t) {}
constexpr operator T() const { return t; }
constexpr explicit operator bool() const { return underlying(t); }
};

template <typename T> using Underlying = std::underlying_type_t<T>;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: no header providing "std::underlying_type_t" is directly included [misc-include-cleaner]

include/CppInterOp/CppInterOp.h:22:

- #include <vector>
+ #include <type_traits>
+ #include <vector>

template <typename T> constexpr Underlying<T> underlying(T t) {
return Underlying<T>(t);
}

enum class Operator : unsigned char {
OP_None,
OP_New,
OP_Delete,
Expand Down Expand Up @@ -93,18 +105,31 @@ enum Operator : unsigned char {
OP_Coawait,
};

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

constexpr TruthValue<OperatorArity> operator&(OperatorArity l,
OperatorArity r) {
return OperatorArity(underlying(l) & underlying(r));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I do not think arity could be xor-ed -- we have already kBoth.

}

constexpr TruthValue<OperatorArity> operator|(OperatorArity l,
OperatorArity r) {
return OperatorArity(underlying(l) | underlying(r));
}

/// Enum modelling CVR qualifiers.
enum QualKind : unsigned char {
enum class QualKind : unsigned char {
Const = 1 << 0,
Volatile = 1 << 1,
Restrict = 1 << 2
};

inline QualKind operator|(QualKind a, QualKind b) {
return static_cast<QualKind>(static_cast<unsigned char>(a) |
static_cast<unsigned char>(b));
constexpr TruthValue<QualKind> operator&(QualKind l, QualKind r) {
return QualKind(underlying(l) & underlying(r));
}

constexpr TruthValue<QualKind> operator|(QualKind l, QualKind r) {
return QualKind(underlying(l) | underlying(r));
}

/// A class modeling function calls for functions produced by the interpreter
Expand Down Expand Up @@ -686,7 +711,7 @@ CPPINTEROP_API OperatorArity GetOperatorArity(TCppFunction_t op);
///\returns list of operator overloads
CPPINTEROP_API void GetOperator(TCppScope_t scope, Operator op,
std::vector<TCppFunction_t>& operators,
OperatorArity kind = kBoth);
OperatorArity kind = OperatorArity::kBoth);

/// Creates an owned instance of the interpreter we need for the various interop
/// services and pushes it onto a stack.
Expand Down
6 changes: 3 additions & 3 deletions lib/CppInterOp/CppInterOp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3874,11 +3874,11 @@ OperatorArity GetOperatorArity(TCppFunction_t op) {
#define OVERLOADED_OPERATOR(Name, Spelling, Token, Unary, Binary, MemberOnly) \
case OO_##Name: \
if ((Unary) && (Binary)) \
return kBoth; \
return OperatorArity::kBoth; \
if (Unary) \
return kUnary; \
return OperatorArity::kUnary; \
if (Binary) \
return kBinary; \
return OperatorArity::kBinary; \
break;
#include "clang/Basic/OperatorKinds.def"
default:
Expand Down
8 changes: 4 additions & 4 deletions unittests/CppInterOp/FunctionReflectionTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1858,7 +1858,7 @@ TYPED_TEST(CppInterOpTest, FunctionReflectionTestGetFunctionCallWrapper) {

EXPECT_TRUE(toperator);
std::vector<Cpp::TCppScope_t> operators;
Cpp::GetOperator(TOperator, Cpp::OP_Less, operators);
Cpp::GetOperator(TOperator, Cpp::Operator::OP_Less, operators);
EXPECT_EQ(operators.size(), 1);

Cpp::TCppScope_t op_templated = operators[0];
Expand Down Expand Up @@ -1901,8 +1901,8 @@ TYPED_TEST(CppInterOpTest, FunctionReflectionTestGetFunctionCallWrapper) {
Cpp::TCppType_t K1 = Cpp::GetTypeFromScope(Cpp::GetNamed("K1"));
Cpp::TCppType_t K2 = Cpp::GetTypeFromScope(Cpp::GetNamed("K2"));
operators.clear();
Cpp::GetOperator(Cpp::GetScope("N2", Cpp::GetScope("N1")), Cpp::OP_Plus,
operators);
Cpp::GetOperator(Cpp::GetScope("N2", Cpp::GetScope("N1")),
Cpp::Operator::OP_Plus, operators);
EXPECT_EQ(operators.size(), 1);
Cpp::TCppFunction_t kop =
Cpp::BestOverloadFunctionMatch(operators, {}, {K1, K2});
Expand Down Expand Up @@ -2132,7 +2132,7 @@ TYPED_TEST(CppInterOpTest, FunctionReflectionTestGetFunctionCallWrapper) {
EXPECT_TRUE(KlassProduct_float);

operators.clear();
Cpp::GetOperator(KlassProduct_int, Cpp::OP_Star, operators);
Cpp::GetOperator(KlassProduct_int, Cpp::Operator::OP_Star, operators);
EXPECT_EQ(operators.size(), 2);

op = Cpp::BestOverloadFunctionMatch(
Expand Down
10 changes: 5 additions & 5 deletions unittests/CppInterOp/TypeReflectionTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -614,11 +614,11 @@ TYPED_TEST(CppInterOpTest, TypeReflectionTestIsFunctionPointerType) {
}

TYPED_TEST(CppInterOpTest, TypeReflectionTestOperatorSpelling) {
EXPECT_EQ(Cpp::GetSpellingFromOperator(Cpp::OP_Less), "<");
EXPECT_EQ(Cpp::GetSpellingFromOperator(Cpp::OP_Plus), "+");
EXPECT_EQ(Cpp::GetOperatorFromSpelling("->"), Cpp::OP_Arrow);
EXPECT_EQ(Cpp::GetOperatorFromSpelling("()"), Cpp::OP_Call);
EXPECT_EQ(Cpp::GetOperatorFromSpelling("invalid"), Cpp::OP_None);
EXPECT_EQ(Cpp::GetSpellingFromOperator(Cpp::Operator::OP_Less), "<");
EXPECT_EQ(Cpp::GetSpellingFromOperator(Cpp::Operator::OP_Plus), "+");
EXPECT_EQ(Cpp::GetOperatorFromSpelling("->"), Cpp::Operator::OP_Arrow);
EXPECT_EQ(Cpp::GetOperatorFromSpelling("()"), Cpp::Operator::OP_Call);
EXPECT_EQ(Cpp::GetOperatorFromSpelling("invalid"), Cpp::Operator::OP_None);
}

TYPED_TEST(CppInterOpTest, TypeReflectionTestTypeQualifiers) {
Expand Down
Loading