Skip to content

Commit 8277fe9

Browse files
Update GetBinaryOperator to GetOperator
resolving unary operators and operators defined within namespaces
1 parent ef2f0a1 commit 8277fe9

File tree

3 files changed

+128
-54
lines changed

3 files changed

+128
-54
lines changed

include/clang/Interpreter/CppInterOp.h

Lines changed: 59 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -37,42 +37,57 @@ namespace Cpp {
3737
using TInterp_t = void*;
3838
using TCppObject_t = void*;
3939

40-
enum BinaryOperator {
41-
PtrMemD = 0,
42-
PtrMemI,
43-
Mul,
44-
Div,
45-
Rem,
46-
Add,
47-
Sub,
48-
Shl,
49-
Shr,
50-
Cmp,
51-
LT,
52-
GT,
53-
LE,
54-
GE,
55-
EQ,
56-
NE,
57-
And,
58-
Xor,
59-
Or,
60-
LAnd,
61-
LOr,
62-
Assign,
63-
MulAssign,
64-
DivAssign,
65-
RemAssign,
66-
AddAssign,
67-
SubAssign,
68-
ShlAssign,
69-
ShrAssign,
70-
AndAssign,
71-
XorAssign,
72-
OrAssign,
73-
Comma,
40+
enum Operator {
41+
OP_None,
42+
OP_New,
43+
OP_Delete,
44+
OP_Array_New,
45+
OP_Array_Delete,
46+
OP_Plus,
47+
OP_Minus,
48+
OP_Star,
49+
OP_Slash,
50+
OP_Percent,
51+
OP_Caret,
52+
OP_Amp,
53+
OP_Pipe,
54+
OP_Tilde,
55+
OP_Exclaim,
56+
OP_Equal,
57+
OP_Less,
58+
OP_Greater,
59+
OP_PlusEqual,
60+
OP_MinusEqual,
61+
OP_StarEqual,
62+
OP_SlashEqual,
63+
OP_PercentEqual,
64+
OP_CaretEqual,
65+
OP_AmpEqual,
66+
OP_PipeEqual,
67+
OP_LessLess,
68+
OP_GreaterGreater,
69+
OP_LessLessEqual,
70+
OP_GreaterGreaterEqual,
71+
OP_EqualEqual,
72+
OP_ExclaimEqual,
73+
OP_LessEqual,
74+
OP_GreaterEqual,
75+
OP_Spaceship,
76+
OP_AmpAmp,
77+
OP_PipePipe,
78+
OP_PlusPlus,
79+
OP_MinusMinus,
80+
OP_Comma,
81+
OP_ArrowStar,
82+
OP_Arrow,
83+
OP_Call,
84+
OP_Subscript,
85+
OP_Conditional,
86+
OP_Coawait,
7487
};
7588

89+
enum OperatorArity { kUnary = 1, kBinary, kBoth };
90+
7691
/// A class modeling function calls for functions produced by the interpreter
7792
/// in compiled code. It provides an information if we are calling a standard
7893
/// function, constructor or destructor.
@@ -512,9 +527,16 @@ namespace Cpp {
512527
CPPINTEROP_API std::string GetFunctionArgName(TCppFunction_t func,
513528
TCppIndex_t param_index);
514529

515-
///\returns function that performs operation op on lc and rc
516-
void GetBinaryOperator(TCppScope_t scope, enum BinaryOperator op,
517-
std::vector<TCppFunction_t>& operators);
530+
///\returns true if scope is a unary operator
531+
bool IsUnaryOperator(TCppScope_t scope);
532+
533+
///\returns true if scope is a binary operator
534+
bool IsBinaryOperator(TCppScope_t scope);
535+
536+
///\returns list of operator overloads
537+
void GetOperator(TCppScope_t scope, Operator op,
538+
std::vector<TCppFunction_t>& operators,
539+
OperatorArity kind = kBoth);
518540

519541
/// Creates an instance of the interpreter we need for the various interop
520542
/// services.

lib/Interpreter/CppInterOp.cpp

Lines changed: 46 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3262,22 +3262,56 @@ namespace Cpp {
32623262
return PI->getNameAsString();
32633263
}
32643264

3265-
void GetBinaryOperator(TCppScope_t scope, enum BinaryOperator op,
3266-
std::vector<TCppFunction_t>& operators) {
3265+
bool IsUnaryOperator(TCppScope_t scope) {
32673266
Decl* D = static_cast<Decl*>(scope);
3268-
auto* DC = llvm::dyn_cast<DeclContext>(D);
3269-
Scope* S = getSema().getScopeForContext(DC);
3270-
if (!S)
3271-
return;
3267+
if (auto* FD = llvm::dyn_cast<FunctionDecl>(D)) {
3268+
if (FD->isOverloadedOperator()) {
3269+
switch (FD->getOverloadedOperator()) {
3270+
#define OVERLOADED_OPERATOR(Name, Spelling, Token, Unary, Binary, \
3271+
MemberOnly) \
3272+
case OO_##Name: \
3273+
return Unary;
3274+
#include "clang/Basic/OperatorKinds.def"
3275+
default:
3276+
break;
3277+
}
3278+
}
3279+
}
3280+
return false;
3281+
}
32723282

3273-
clang::UnresolvedSet<8> lookup;
3283+
bool IsBinaryOperator(TCppScope_t scope) {
3284+
Decl* D = static_cast<Decl*>(scope);
3285+
if (auto* FD = llvm::dyn_cast<FunctionDecl>(D)) {
3286+
if (FD->isOverloadedOperator()) {
3287+
switch (FD->getOverloadedOperator()) {
3288+
#define OVERLOADED_OPERATOR(Name, Spelling, Token, Unary, Binary, \
3289+
MemberOnly) \
3290+
case OO_##Name: \
3291+
return Binary;
3292+
#include "clang/Basic/OperatorKinds.def"
3293+
default:
3294+
break;
3295+
}
3296+
}
3297+
}
3298+
return false;
3299+
}
32743300

3275-
getSema().LookupBinOp(S, SourceLocation(), (clang::BinaryOperatorKind)op,
3276-
lookup);
3301+
void GetOperator(TCppScope_t scope, Operator op,
3302+
std::vector<TCppFunction_t>& operators, OperatorArity kind) {
3303+
Decl* D = static_cast<Decl*>(scope);
3304+
if (auto* DC = llvm::dyn_cast_or_null<DeclContext>(D)) {
3305+
ASTContext& C = getSema().getASTContext();
3306+
DeclContextLookupResult Result =
3307+
DC->lookup(C.DeclarationNames.getCXXOperatorName(
3308+
(clang::OverloadedOperatorKind)op));
32773309

3278-
for (NamedDecl* D : lookup) {
3279-
if (auto* FD = llvm::dyn_cast<Decl>(D))
3280-
operators.push_back(FD);
3310+
for (auto* i : Result) {
3311+
if (((kind & OperatorArity::kBinary) && (IsBinaryOperator(i))) ||
3312+
((kind & OperatorArity::kUnary) && (IsUnaryOperator(i))))
3313+
operators.push_back(i);
3314+
}
32813315
}
32823316
}
32833317

unittests/CppInterOp/ScopeReflectionTest.cpp

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -967,7 +967,7 @@ TEST(ScopeReflectionTest, IncludeVector) {
967967
Interp->process(code);
968968
}
969969

970-
TEST(ScopeReflectionTest, GetBinaryOperator) {
970+
TEST(ScopeReflectionTest, GetOperator) {
971971
if (llvm::sys::RunningOnValgrind())
972972
GTEST_SKIP() << "XFAIL due to Valgrind report";
973973

@@ -988,27 +988,45 @@ TEST(ScopeReflectionTest, GetBinaryOperator) {
988988
return MyClass(lhs.x + rhs.x);
989989
}
990990
991+
namespace extra_ops {
992+
991993
MyClass operator+(MyClass lhs, int rhs) {
992994
return MyClass(lhs.x + rhs);
993995
}
994996
995997
MyClass operator+(int lhs, MyClass rhs) {
996998
return MyClass(lhs + rhs.x);
997999
}
1000+
1001+
MyClass operator~(MyClass self) {
1002+
return MyClass(-self.x);
1003+
}
1004+
1005+
}
9981006
)";
9991007

10001008
Cpp::Declare(code.c_str());
10011009

10021010
std::vector<Cpp::TCppFunction_t> ops;
10031011

1004-
Cpp::GetBinaryOperator(Cpp::GetGlobalScope(), Cpp::BinaryOperator::Add, ops);
1005-
EXPECT_EQ(ops.size(), 3);
1012+
Cpp::GetOperator(Cpp::GetGlobalScope(), Cpp::Operator::OP_Plus, ops);
1013+
EXPECT_EQ(ops.size(), 1);
10061014
ops.clear();
10071015

1008-
Cpp::GetBinaryOperator(Cpp::GetGlobalScope(), Cpp::BinaryOperator::Sub, ops);
1016+
Cpp::GetOperator(Cpp::GetGlobalScope(), Cpp::Operator::OP_Minus, ops);
10091017
EXPECT_EQ(ops.size(), 1);
10101018
ops.clear();
10111019

1012-
Cpp::GetBinaryOperator(Cpp::GetGlobalScope(), Cpp::BinaryOperator::Mul, ops);
1020+
Cpp::GetOperator(Cpp::GetGlobalScope(), Cpp::Operator::OP_Star, ops);
10131021
EXPECT_EQ(ops.size(), 0);
1022+
ops.clear();
1023+
1024+
// operators defined within a namespace
1025+
Cpp::GetOperator(Cpp::GetScope("extra_ops"), Cpp::Operator::OP_Plus, ops);
1026+
EXPECT_EQ(ops.size(), 2);
1027+
ops.clear();
1028+
1029+
// unary operator
1030+
Cpp::GetOperator(Cpp::GetScope("extra_ops"), Cpp::Operator::OP_Tilde, ops);
1031+
EXPECT_EQ(ops.size(), 1);
10141032
}

0 commit comments

Comments
 (0)