https://github.com/Serafean updated 
https://github.com/llvm/llvm-project/pull/216553

From 3360ccc8b37ffd068b554bb917aff211bed86d20 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Martin=20Bedn=C3=A1r?= <[email protected]>
Date: Sun, 16 Aug 2026 00:00:07 +0200
Subject: [PATCH 1/2] Report operator kind for Declarations and Exprs

---
 clang/docs/ReleaseNotes.md      |  1 +
 clang/tools/libclang/CIndex.cpp | 54 +++++++++++++++++++++++++++++++++
 2 files changed, 55 insertions(+)

diff --git a/clang/docs/ReleaseNotes.md b/clang/docs/ReleaseNotes.md
index c348ddaf23017..b312bde887615 100644
--- a/clang/docs/ReleaseNotes.md
+++ b/clang/docs/ReleaseNotes.md
@@ -476,6 +476,7 @@ features cannot lower the translation-unit ABI level;
 ### libclang
 
 - visit identifier initializers in lambda capture as VarDecl instead of 
VariableRef. Warning: this changes behaviour.
+- Allow querying Unary and Binary operator types on declaration cursors.
 
 ### Code Completion
 
diff --git a/clang/tools/libclang/CIndex.cpp b/clang/tools/libclang/CIndex.cpp
index 7c9da867909f5..83b9842fb0db2 100644
--- a/clang/tools/libclang/CIndex.cpp
+++ b/clang/tools/libclang/CIndex.cpp
@@ -10224,6 +10224,16 @@ CXString clang_getBinaryOperatorKindSpelling(enum 
CXBinaryOperatorKind kind) {
 }
 
 enum CXBinaryOperatorKind clang_getCursorBinaryOperatorKind(CXCursor cursor) {
+
+  auto retOp = [](OverloadedOperatorKind Kind, int numArgs) {
+    if (!(Kind == OO_None || Kind == OO_PlusPlus || Kind == OO_MinusMinus ||
+          numArgs != 2)) {
+      auto opcode = BinaryOperator::getOverloadedOpcode(Kind);
+      return static_cast<CXBinaryOperatorKind>(opcode + 1);
+    }
+    return CXBinaryOperator_Invalid;
+  };
+
   if (clang_isExpression(cursor.kind)) {
     const Expr *expr = getCursorExpr(cursor);
 
@@ -10232,6 +10242,22 @@ enum CXBinaryOperatorKind 
clang_getCursorBinaryOperatorKind(CXCursor cursor) {
 
     if (const auto *op = dyn_cast<CXXRewrittenBinaryOperator>(expr))
       return static_cast<CXBinaryOperatorKind>(op->getOpcode() + 1);
+
+    if (const auto *OCE = dyn_cast<CXXOperatorCallExpr>(expr)) {
+      return retOp(OCE->getOperator(), OCE->getNumArgs());
+    }
+  }
+
+  if (clang_isDeclaration(cursor.kind)) {
+    const auto *decl = getCursorDecl(cursor);
+
+    const auto *funcDecl = dyn_cast<FunctionDecl>(decl);
+    if (!funcDecl)
+      return CXBinaryOperator_Invalid;
+
+    return retOp(funcDecl->getOverloadedOperator(),
+                 (funcDecl->isCXXClassMember()) ? funcDecl->getNumParams() + 1
+                                                : funcDecl->getNumParams());
   }
 
   return CXBinaryOperator_Invalid;
@@ -10246,11 +10272,39 @@ CXString clang_getUnaryOperatorKindSpelling(enum 
CXUnaryOperatorKind kind) {
 }
 
 enum CXUnaryOperatorKind clang_getCursorUnaryOperatorKind(CXCursor cursor) {
+
+  auto retOp = [](OverloadedOperatorKind op, int argNum) {
+    const bool postfix =
+        argNum == 2 && (op == OO_PlusPlus || op == OO_MinusMinus);
+
+    if (op == OO_None || (!postfix && argNum != 1))
+      return CXUnaryOperator_Invalid;
+
+    const auto uop = UnaryOperator::getOverloadedOpcode(op, postfix);
+    return static_cast<CXUnaryOperatorKind>(uop + 1);
+  };
+
   if (clang_isExpression(cursor.kind)) {
     const Expr *expr = getCursorExpr(cursor);
 
     if (const auto *op = dyn_cast<UnaryOperator>(expr))
       return static_cast<CXUnaryOperatorKind>(op->getOpcode() + 1);
+
+    if (const auto *OCE = dyn_cast<CXXOperatorCallExpr>(expr)) {
+      return retOp(OCE->getOperator(), OCE->getNumArgs());
+    }
+  }
+
+  if (clang_isDeclaration(cursor.kind)) {
+    const auto *decl = getCursorDecl(cursor);
+
+    const auto *funcDecl = dyn_cast<FunctionDecl>(decl);
+    if (!funcDecl)
+      return CXUnaryOperator_Invalid;
+
+    return retOp(funcDecl->getOverloadedOperator(),
+                 (funcDecl->isCXXClassMember()) ? funcDecl->getNumParams() + 1
+                                                : funcDecl->getNumParams());
   }
 
   return CXUnaryOperator_Invalid;

From ae1bf6c9375baeabce1ddce33db382adae7bf46e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Martin=20Bedn=C3=A1r?= <[email protected]>
Date: Sun, 16 Aug 2026 00:01:02 +0200
Subject: [PATCH 2/2] tests

---
 clang/test/Index/binop.cpp              | 435 ++++++++++++++++++++++++
 clang/test/Index/unop.cpp               | 175 ++++++++++
 clang/tools/c-index-test/c-index-test.c |  22 +-
 3 files changed, 631 insertions(+), 1 deletion(-)
 create mode 100644 clang/test/Index/unop.cpp

diff --git a/clang/test/Index/binop.cpp b/clang/test/Index/binop.cpp
index 576fd73cc2abf..91079385d2d4f 100644
--- a/clang/test/Index/binop.cpp
+++ b/clang/test/Index/binop.cpp
@@ -90,3 +90,438 @@ void func(void) {
 // CHECK: CompoundAssignOperator=^= BinOp=^= 31
 // CHECK: CompoundAssignOperator=|= BinOp=|= 32
 // CHECK: BinaryOperator=, BinOp=, 33
+
+struct D {
+  D() = default;
+  D& operator+(){return *this;}
+  D& operator-(){return *this;}
+  int& operator->*(int D::*i){return this->i;}
+  D& operator*(const D&){return *this;}
+  D& operator/(const D&){return *this;}
+  D& operator%(const D&){return *this;}
+  D& operator+(const D&){return *this;}
+  D& operator-(const D&){return *this;}
+  D& operator<<(const D&){return *this;}
+  D& operator>>(const D&){return *this;}
+  bool operator<(const D&){return true;}
+  bool operator>(const D&){return true;}
+  bool operator<=(const D&){return true;}
+  bool operator>=(const D&){return true;}
+  bool operator==(const D&){return true;}
+  bool operator!=(const D&){return true;}
+  D& operator&(const D&){return *this;}
+  D& operator^(const D&){return *this;}
+  D& operator|(const D&){return *this;}
+  bool operator&&(const D&){return true;}
+  bool operator||(const D&){return true;}
+  D& operator=(const D&);
+  D& operator*=(const D&){return *this;}
+  D& operator/=(const D&){return *this;}
+  D& operator%=(const D&){return *this;}
+  D& operator+=(const D&){return *this;}
+  D& operator-=(const D&){return *this;}
+  D& operator<<=(const D&){return *this;}
+  D& operator>>=(const D&){return *this;}
+  D& operator&=(const D&){return *this;}
+  D& operator^=(const D&){return *this;}
+  D& operator|=(const D&){return *this;}
+  D& operator,(const D&){return *this;}
+
+  // Negative test of --/++
+  D& operator++(int){return *this;};
+  D& operator++(){return *this;};
+  D& operator--(int){return *this;};
+  D& operator--(){return *this;};
+  void foo();
+  int i;
+};
+
+// CHECK: CXXMethod=operator+:96:6 (Definition) BinOp= 0
+// CHECK: CXXMethod=operator-:97:6 (Definition) BinOp= 0
+// CHECK: CXXMethod=operator->*:98:8 (Definition) BinOp=->* 2
+// CHECK: CXXMethod=operator*:99:6 (Definition) BinOp=* 3
+// CHECK: CXXMethod=operator/:100:6 (Definition) BinOp=/ 4
+// CHECK: CXXMethod=operator%:101:6 (Definition) BinOp=% 5
+// CHECK: CXXMethod=operator+:102:6 (Definition) BinOp=+ 6
+// CHECK: CXXMethod=operator-:103:6 (Definition) BinOp=- 7
+// CHECK: CXXMethod=operator<<:104:6 (Definition) BinOp=<< 8
+// CHECK: CXXMethod=operator>>:105:6 (Definition) BinOp=>> 9
+// CHECK: CXXMethod=operator<:106:8 (Definition) BinOp=< 11
+// CHECK: CXXMethod=operator>:107:8 (Definition) BinOp=> 12
+// CHECK: CXXMethod=operator<=:108:8 (Definition) BinOp=<= 13
+// CHECK: CXXMethod=operator>=:109:8 (Definition) BinOp=>= 14
+// CHECK: CXXMethod=operator==:110:8 (Definition) BinOp=== 15
+// CHECK: CXXMethod=operator!=:111:8 (Definition) BinOp=!= 16
+// CHECK: CXXMethod=operator&:112:6 (Definition) BinOp=& 17
+// CHECK: CXXMethod=operator^:113:6 (Definition) BinOp=^ 18
+// CHECK: CXXMethod=operator|:114:6 (Definition) BinOp=| 19
+// CHECK: CXXMethod=operator&&:115:8 (Definition) BinOp=&& 20
+// CHECK: CXXMethod=operator||:116:8 (Definition) BinOp=|| 21
+// CHECK: CXXMethod=operator=:117:6 (copy-assignment operator) BinOp== 22
+// CHECK: CXXMethod=operator*=:118:6 (Definition) BinOp=*= 23
+// CHECK: CXXMethod=operator/=:119:6 (Definition) BinOp=/= 24
+// CHECK: CXXMethod=operator%=:120:6 (Definition) BinOp=%= 25
+// CHECK: CXXMethod=operator+=:121:6 (Definition) BinOp=+= 26
+// CHECK: CXXMethod=operator-=:122:6 (Definition) BinOp=-= 27
+// CHECK: CXXMethod=operator<<=:123:6 (Definition) BinOp=<<= 28
+// CHECK: CXXMethod=operator>>=:124:6 (Definition) BinOp=>>= 29
+// CHECK: CXXMethod=operator&=:125:6 (Definition) BinOp=&= 30
+// CHECK: CXXMethod=operator^=:126:6 (Definition) BinOp=^= 31
+// CHECK: CXXMethod=operator|=:127:6 (Definition) BinOp=|= 32
+// CHECK: CXXMethod=operator,:128:6 (Definition) BinOp=, 33
+// CHECK: CXXMethod=operator++:131:6 (Definition) BinOp= 0
+// CHECK: CXXMethod=operator++:132:6 (Definition) BinOp= 0
+// CHECK: CXXMethod=operator--:133:6 (Definition) BinOp= 0
+// CHECK: CXXMethod=operator--:134:6 (Definition) BinOp= 0
+// CHECK: CXXMethod=foo:135:8 BinOp= 0
+
+
+void func2(void) {
+  #pragma clang diagnostic push
+  #pragma clang diagnostic ignored "-Wunused-value"
+  D a, b;
+  int D::*p = &D::i;
+  
+  D *pc;
+  a->*p;
+  
+  a *b;
+  a / b;
+  a % b;
+  a + b;
+  a - b;
+  
+  a << b;
+  a >> b;
+  
+  a < b;
+  a > b;
+  
+  a <= b;
+  a >= b;
+  a == b;
+  a != b;
+  
+  a &b;
+  a ^ b;
+  a | b;
+  
+  a &&b;
+  a || b;
+  
+  a = b;
+  
+  a *= b;
+  a /= b;
+  a %= b;
+  a += b;
+  a -= b;
+  
+  a <<= b;
+  a >>= b;
+  
+  a &= b;
+  a ^= b;
+  a |= b;
+  a, b;
+  
+  // Negative test
+  a++;
+  ++a;
+  a--;
+  --a;
+  
+  +a;
+  -a;
+  #pragma clang diagnostic pop
+}
+
+// CHECK: FunctionDecl=func2:179:6 (Definition) BinOp= 0
+// CHECK: CallExpr=D:95:3 BinOp= 0
+// CHECK: CallExpr=D:95:3 BinOp= 0
+// CHECK: CallExpr=operator->*:98:8 BinOp=->* 2
+// CHECK: CallExpr=operator*:99:6 BinOp=* 3
+// CHECK: CallExpr=operator/:100:6 BinOp=/ 4
+// CHECK: CallExpr=operator%:101:6 BinOp=% 5
+// CHECK: CallExpr=operator+:102:6 BinOp=+ 6
+// CHECK: CallExpr=operator-:103:6 BinOp=- 7
+// CHECK: CallExpr=operator<<:104:6 BinOp=<< 8
+// CHECK: CallExpr=operator>>:105:6 BinOp=>> 9
+// CHECK: CallExpr=operator<:106:8 BinOp=< 11
+// CHECK: CallExpr=operator>:107:8 BinOp=> 12
+// CHECK: CallExpr=operator<=:108:8 BinOp=<= 13
+// CHECK: CallExpr=operator>=:109:8 BinOp=>= 14
+// CHECK: CallExpr=operator==:110:8 BinOp=== 15
+// CHECK: CallExpr=operator!=:111:8 BinOp=!= 16
+// CHECK: CallExpr=operator&:112:6 BinOp=& 17
+// CHECK: CallExpr=operator^:113:6 BinOp=^ 18
+// CHECK: CallExpr=operator|:114:6 BinOp=| 19
+// CHECK: CallExpr=operator&&:115:8 BinOp=&& 20
+// CHECK: CallExpr=operator||:116:8 BinOp=|| 21
+// CHECK: CallExpr=operator=:117:6 BinOp== 22
+// CHECK: CallExpr=operator*=:118:6 BinOp=*= 23
+// CHECK: CallExpr=operator/=:119:6 BinOp=/= 24
+// CHECK: CallExpr=operator%=:120:6 BinOp=%= 25
+// CHECK: CallExpr=operator+=:121:6 BinOp=+= 26
+// CHECK: CallExpr=operator-=:122:6 BinOp=-= 27
+// CHECK: CallExpr=operator<<=:123:6 BinOp=<<= 28
+// CHECK: CallExpr=operator>>=:124:6 BinOp=>>= 29
+// CHECK: CallExpr=operator&=:125:6 BinOp=&= 30
+// CHECK: CallExpr=operator^=:126:6 BinOp=^= 31
+// CHECK: CallExpr=operator|=:127:6 BinOp=|= 32
+// CHECK: CallExpr=operator,:128:6 BinOp=, 33
+// CHECK: CallExpr=operator++:131:6 BinOp= 0
+// CHECK: CallExpr=operator++:132:6 BinOp= 0
+// CHECK: CallExpr=operator--:133:6 BinOp= 0
+// CHECK: CallExpr=operator--:134:6 BinOp= 0
+// CHECK: CallExpr=operator+:96:6 BinOp= 0
+// CHECK: CallExpr=operator-:97:6 BinOp= 0
+
+
+struct E{
+  int i;
+};
+
+int& operator->*(const E&, int E::*i);
+E operator*(const E&, const E&);
+E operator/(const E&, const E&);
+E operator%(const E&, const E&);
+E operator+(const E&, const E&);
+E operator-(const E&, const E&);
+E operator<<(const E&, const E&);
+E operator>>(const E&, const E&);
+bool operator<(const E&, const E&);
+bool operator>(const E&, const E&);
+bool operator<=(const E&, const E&);
+bool operator>=(const E&, const E&);
+bool operator==(const E&, const E&);
+bool operator!=(const E&, const E&);
+E operator&(const E&, const E&);
+E operator^(const E&, const E&);
+E operator|(const E&, const E&);
+bool operator&&(const E&, const E&);
+bool operator||(const E&, const E&);
+E operator*=(const E&, const E&);
+E operator/=(const E&, const E&);
+E operator%=(const E&, const E&);
+E operator+=(const E&, const E&);
+E operator-=(const E&, const E&);
+E operator<<=(const E&, const E&);
+E operator>>=(const E&, const E&);
+E operator&=(const E&, const E&);
+E operator^=(const E&, const E&);
+E operator|=(const E&, const E&);
+E operator,(const E&, const E&);
+E operator++(const E&a, int);
+E operator++(const E&a );
+E operator--(const E&a, int);
+E operator--(const E&a);
+void foo(const E&, const E&);
+E operator+(const E&);
+E operator-(const E&);
+
+// CHECK: FunctionDecl=operator->*:285:6 BinOp=->* 2
+// CHECK: FunctionDecl=operator*:286:3 BinOp=* 3
+// CHECK: FunctionDecl=operator/:287:3 BinOp=/ 4
+// CHECK: FunctionDecl=operator%:288:3 BinOp=% 5
+// CHECK: FunctionDecl=operator+:289:3 BinOp=+ 6
+// CHECK: FunctionDecl=operator-:290:3 BinOp=- 7
+// CHECK: FunctionDecl=operator<<:291:3 BinOp=<< 8
+// CHECK: FunctionDecl=operator>>:292:3 BinOp=>> 9
+// CHECK: FunctionDecl=operator<:293:6 BinOp=< 11
+// CHECK: FunctionDecl=operator>:294:6 BinOp=> 12
+// CHECK: FunctionDecl=operator<=:295:6 BinOp=<= 13
+// CHECK: FunctionDecl=operator>=:296:6 BinOp=>= 14
+// CHECK: FunctionDecl=operator==:297:6 BinOp=== 15
+// CHECK: FunctionDecl=operator!=:298:6 BinOp=!= 16
+// CHECK: FunctionDecl=operator&:299:3 BinOp=& 17
+// CHECK: FunctionDecl=operator^:300:3 BinOp=^ 18
+// CHECK: FunctionDecl=operator|:301:3 BinOp=| 19
+// CHECK: FunctionDecl=operator&&:302:6 BinOp=&& 20
+// CHECK: FunctionDecl=operator||:303:6 BinOp=|| 21
+// CHECK: FunctionDecl=operator*=:304:3 BinOp=*= 23
+// CHECK: FunctionDecl=operator/=:305:3 BinOp=/= 24
+// CHECK: FunctionDecl=operator%=:306:3 BinOp=%= 25
+// CHECK: FunctionDecl=operator+=:307:3 BinOp=+= 26
+// CHECK: FunctionDecl=operator-=:308:3 BinOp=-= 27
+// CHECK: FunctionDecl=operator<<=:309:3 BinOp=<<= 28
+// CHECK: FunctionDecl=operator>>=:310:3 BinOp=>>= 29
+// CHECK: FunctionDecl=operator&=:311:3 BinOp=&= 30
+// CHECK: FunctionDecl=operator^=:312:3 BinOp=^= 31
+// CHECK: FunctionDecl=operator|=:313:3 BinOp=|= 32
+// CHECK: FunctionDecl=operator,:314:3 BinOp=, 33
+// CHECK: FunctionDecl=operator++:315:3 BinOp= 0
+// CHECK: FunctionDecl=operator++:316:3 BinOp= 0
+// CHECK: FunctionDecl=operator--:317:3 BinOp= 0
+// CHECK: FunctionDecl=operator--:318:3 BinOp= 0
+// CHECK: FunctionDecl=foo:319:6 BinOp= 0
+// CHECK: FunctionDecl=operator+:320:3 BinOp= 0
+// CHECK: FunctionDecl=operator-:321:3 BinOp= 0
+
+void func3(void) {
+  #pragma clang diagnostic push
+  #pragma clang diagnostic ignored "-Wunused-value"
+  E a, b;
+  int E::*p = &E::i;
+  
+  E *pc;
+  a->*p;
+  
+  a *b;
+  a / b;
+  a % b;
+  a + b;
+  a - b;
+  
+  a << b;
+  a >> b;
+  
+  a < b;
+  a > b;
+  
+  a <= b;
+  a >= b;
+  a == b;
+  a != b;
+  
+  a &b;
+  a ^ b;
+  a | b;
+  
+  a &&b;
+  a || b;
+  
+  a = b;
+  
+  a *= b;
+  a /= b;
+  a %= b;
+  a += b;
+  a -= b;
+  
+  a <<= b;
+  a >>= b;
+  
+  a &= b;
+  a ^= b;
+  a |= b;
+  a, b;
+  
+  // Negative test
+  a++;
+  ++a;
+  a--;
+  --a;
+  
+  +a;
+  -a;
+  #pragma clang diagnostic pop
+}
+
+// CHECK: FunctionDecl=func3:361:6 (Definition) BinOp= 0
+// CHECK: CallExpr=E:281:8 BinOp= 0
+// CHECK: CallExpr=E:281:8 BinOp= 0
+// CHECK: CallExpr=operator->*:285:6 BinOp=->* 2
+// CHECK: CallExpr=operator*:286:3 BinOp=* 3
+// CHECK: CallExpr=operator/:287:3 BinOp=/ 4
+// CHECK: CallExpr=operator%:288:3 BinOp=% 5
+// CHECK: CallExpr=operator+:289:3 BinOp=+ 6
+// CHECK: CallExpr=operator-:290:3 BinOp=- 7
+// CHECK: CallExpr=operator<<:291:3 BinOp=<< 8
+// CHECK: CallExpr=operator>>:292:3 BinOp=>> 9
+// CHECK: CallExpr=operator<:293:6 BinOp=< 11
+// CHECK: CallExpr=operator>:294:6 BinOp=> 12
+// CHECK: CallExpr=operator<=:295:6 BinOp=<= 13
+// CHECK: CallExpr=operator>=:296:6 BinOp=>= 14
+// CHECK: CallExpr=operator==:297:6 BinOp=== 15
+// CHECK: CallExpr=operator!=:298:6 BinOp=!= 16
+// CHECK: CallExpr=operator&:299:3 BinOp=& 17
+// CHECK: CallExpr=operator^:300:3 BinOp=^ 18
+// CHECK: CallExpr=operator|:301:3 BinOp=| 19
+// CHECK: CallExpr=operator&&:302:6 BinOp=&& 20
+// CHECK: CallExpr=operator||:303:6 BinOp=|| 21
+// CHECK: CallExpr=operator=:281:8 BinOp== 22
+// CHECK: CallExpr=operator*=:304:3 BinOp=*= 23
+// CHECK: CallExpr=operator/=:305:3 BinOp=/= 24
+// CHECK: CallExpr=operator%=:306:3 BinOp=%= 25
+// CHECK: CallExpr=operator+=:307:3 BinOp=+= 26
+// CHECK: CallExpr=operator-=:308:3 BinOp=-= 27
+// CHECK: CallExpr=operator<<=:309:3 BinOp=<<= 28
+// CHECK: CallExpr=operator>>=:310:3 BinOp=>>= 29
+// CHECK: CallExpr=operator&=:311:3 BinOp=&= 30
+// CHECK: CallExpr=operator^=:312:3 BinOp=^= 31
+// CHECK: CallExpr=operator|=:313:3 BinOp=|= 32
+// CHECK: CallExpr=operator,:314:3 BinOp=, 33
+// CHECK: CallExpr=operator++:315:3 BinOp= 0
+// CHECK: CallExpr=operator++:316:3 BinOp= 0
+// CHECK: CallExpr=operator--:317:3 BinOp= 0
+// CHECK: CallExpr=operator--:318:3 BinOp= 0
+// CHECK: CallExpr=operator+:320:3 BinOp= 0
+// CHECK: CallExpr=operator-:321:3 BinOp= 0
+
+
+struct space1{
+  int operator<=>(const space1&) const;
+  bool operator==(const space1&) const;
+};
+
+void func4(){
+  #pragma clang diagnostic push
+  #pragma clang diagnostic ignored "-Wunused-value"
+  space1 s1, s2;
+  s1 <=> s2;
+  s1 < s2;
+  s1 > s2;
+  s1 <= s2;
+  s1 >= s2;
+  s1 == s2;
+  s1 != s2;
+#pragma clang diagnostic pop
+}
+
+// CHECK: FunctionDecl=func4:468:6 (Definition) BinOp= 0
+// CHECK: CallExpr=space1:463:8 BinOp= 0
+// CHECK: CallExpr=space1:463:8 BinOp= 0
+// CHECK: CallExpr=operator<=>:464:7 BinOp=<=> 10
+// CHECK: BinaryOperator=< BinOp=< 11
+// CHECK: CallExpr=operator<=>:464:7 BinOp=<=> 10
+// CHECK: BinaryOperator=> BinOp=> 12
+// CHECK: CallExpr=operator<=>:464:7 BinOp=<=> 10
+// CHECK: BinaryOperator=<= BinOp=<= 13
+// CHECK: CallExpr=operator<=>:464:7 BinOp=<=> 10
+// CHECK: BinaryOperator=>= BinOp=>= 14
+// CHECK: CallExpr=operator<=>:464:7 BinOp=<=> 10
+// CHECK: CallExpr=operator==:465:8 BinOp=== 15
+// CHECK: CallExpr=operator==:465:8 BinOp=== 15
+
+struct space2{};
+int operator<=>(const space2&, const space2&);
+bool operator ==(const space2 &, const space2&);
+void func5(){
+  #pragma clang diagnostic push
+  #pragma clang diagnostic ignored "-Wunused-value"
+  space2 s1, s2;
+  s1 <=> s2;
+  s1 < s2;
+  s1 > s2;
+  s1 <= s2;
+  s1 >= s2;
+  s1 == s2;
+  s1 != s2;
+#pragma clang diagnostic pop
+}
+
+// CHECK: FunctionDecl=func5:500:6 (Definition) BinOp= 0
+// CHECK: CallExpr=space2:497:8 BinOp= 0
+// CHECK: CallExpr=space2:497:8 BinOp= 0
+// CHECK: CallExpr=operator<=>:498:5 BinOp=<=> 10
+// CHECK: BinaryOperator=< BinOp=< 11
+// CHECK: CallExpr=operator<=>:498:5 BinOp=<=> 10
+// CHECK: BinaryOperator=> BinOp=> 12
+// CHECK: CallExpr=operator<=>:498:5 BinOp=<=> 10
+// CHECK: BinaryOperator=<= BinOp=<= 13
+// CHECK: CallExpr=operator<=>:498:5 BinOp=<=> 10
+// CHECK: BinaryOperator=>= BinOp=>= 14
+// CHECK: CallExpr=operator<=>:498:5 BinOp=<=> 10
+// CHECK: CallExpr=operator==:499:6 BinOp=== 15
+// CHECK: CallExpr=operator==:499:6 BinOp=== 15
diff --git a/clang/test/Index/unop.cpp b/clang/test/Index/unop.cpp
new file mode 100644
index 0000000000000..56e5fd46a707e
--- /dev/null
+++ b/clang/test/Index/unop.cpp
@@ -0,0 +1,175 @@
+// RUN: c-index-test -test-print-unops -std=c++20 %s | FileCheck %s
+void func(){
+    #pragma clang diagnostic push
+    #pragma clang diagnostic ignored "-Wunused-value"
+    int i;
+    i++;
+    ++i;
+    i--;
+    --i;
+    int *p = &i;
+    *p;
+    int c= +i;
+    int d= -i;
+    ~i;
+    !i;
+    #pragma clang diagnostic pop
+}
+// CHECK: UnaryOperator= UnOp=++ 1
+// CHECK: UnaryOperator= UnOp=++ 3
+// CHECK: UnaryOperator= UnOp=-- 2
+// CHECK: UnaryOperator= UnOp=-- 4
+// CHECK: UnaryOperator= UnOp=& 5
+// CHECK: UnaryOperator= UnOp=* 6
+// CHECK: UnaryOperator= UnOp=+ 7
+// CHECK: UnaryOperator= UnOp=- 8
+// CHECK: UnaryOperator= UnOp=~ 9
+// CHECK: UnaryOperator= UnOp=! 10
+
+struct C{
+    C() = default;
+    C& operator++(int);
+    C& operator++();
+    C& operator--(int);
+    C& operator--();
+    C& operator*();
+    C* operator&();
+    C& operator+();
+    C& operator-();
+    C& operator!();
+    C& operator~();
+    void operator co_await();
+    void foo();
+    C& operator+(const C&);
+    C& operator-(const C&);
+};
+
+// CHECK: CXXMethod=operator++:31:8 UnOp=++ 1
+// CHECK: CXXMethod=operator++:32:8 UnOp=++ 3
+// CHECK: CXXMethod=operator--:33:8 UnOp=-- 2
+// CHECK: CXXMethod=operator--:34:8 UnOp=-- 4
+// CHECK: CXXMethod=operator*:35:8 UnOp=* 6
+// CHECK: CXXMethod=operator&:36:8 UnOp=& 5
+// CHECK: CXXMethod=operator+:37:8 UnOp=+ 7
+// CHECK: CXXMethod=operator-:38:8 UnOp=- 8
+// CHECK: CXXMethod=operator!:39:8 UnOp=! 10
+// CHECK: CXXMethod=operator~:40:8 UnOp=~ 9
+// CHECK: CXXMethod=operator co_await:41:10 UnOp=co_await 14
+// CHECK: CXXMethod=foo:42:10 UnOp= 0
+// CHECK: CXXMethod=operator+:43:8 UnOp= 0
+// CHECK: CXXMethod=operator-:44:8 UnOp= 0
+
+void func2(){
+    #pragma clang diagnostic push
+    #pragma clang diagnostic ignored "-Wunused-value"
+    C i;
+    i++;
+    ++i;
+    i--;
+    --i;
+    C *p = &i;
+    *i;
+    +i;
+    C n = +i;
+    -i;
+    C m = -i;
+    
+    ~i;
+    !i;
+    
+    i + i;
+    i - i;
+    #pragma clang diagnostic pop
+}
+
+// CHECK: CallExpr=C:30:5 UnOp= 0
+// CHECK: CallExpr=operator++:31:8 UnOp=++ 1
+// CHECK: CallExpr=operator++:32:8 UnOp=++ 3
+// CHECK: CallExpr=operator--:33:8 UnOp=-- 2
+// CHECK: CallExpr=operator--:34:8 UnOp=-- 4
+// CHECK: CallExpr=operator&:36:8 UnOp=& 5
+// CHECK: CallExpr=operator*:35:8 UnOp=* 6
+// CHECK: CallExpr=operator+:37:8 UnOp=+ 7
+// CHECK: CallExpr=C:29:8 UnOp= 0
+// CHECK: CallExpr=operator+:37:8 UnOp=+ 7
+// CHECK: CallExpr=operator-:38:8 UnOp=- 8
+// CHECK: CallExpr=C:29:8 UnOp= 0
+// CHECK: CallExpr=operator-:38:8 UnOp=- 8
+// CHECK: CallExpr=operator~:40:8 UnOp=~ 9
+// CHECK: CallExpr=operator!:39:8 UnOp=! 10
+// CHECK: CallExpr=operator+:43:8 UnOp= 0
+// CHECK: CallExpr=operator-:44:8 UnOp= 0
+
+
+struct D {
+    
+};
+
+D operator++(const D&a, int);
+D operator++(const D&a );
+D operator--(const D&a, int);
+D operator--(const D&a);
+D operator*(const D&a);
+D operator&(const D&a);
+D operator+(const D&a);
+D operator-(const D&a);
+D operator!(const D&a);
+D operator~(const D&a);
+void operator co_await(const D &d);
+void foo(const D&);
+D operator+(const D&a, const D&);
+D operator-(const D&a, const D&);
+
+// CHECK: FunctionDecl=operator++:108:3 UnOp=++ 1
+// CHECK: FunctionDecl=operator++:109:3 UnOp=++ 3
+// CHECK: FunctionDecl=operator--:110:3 UnOp=-- 2
+// CHECK: FunctionDecl=operator--:111:3 UnOp=-- 4
+// CHECK: FunctionDecl=operator*:112:3 UnOp=* 6
+// CHECK: FunctionDecl=operator&:113:3 UnOp=& 5
+// CHECK: FunctionDecl=operator+:114:3 UnOp=+ 7
+// CHECK: FunctionDecl=operator-:115:3 UnOp=- 8
+// CHECK: FunctionDecl=operator!:116:3 UnOp=! 10
+// CHECK: FunctionDecl=operator~:117:3 UnOp=~ 9
+// CHECK: FunctionDecl=operator co_await:118:6 UnOp=co_await 14
+// CHECK: FunctionDecl=foo:119:6 UnOp= 0
+// CHECK: FunctionDecl=operator+:120:3 UnOp= 0
+// CHECK: FunctionDecl=operator-:121:3 UnOp= 0
+
+void func3(){
+    #pragma clang diagnostic push
+    #pragma clang diagnostic ignored "-Wunused-value"
+    D i;
+    i++;
+    ++i;
+    i--;
+    --i;
+     &i;
+    *i;
+    +i;
+    D n = +i;
+    -i;
+    D m = -i;
+    
+    ~i;
+    !i;
+    i + i;
+    i - i;
+    
+    #pragma clang diagnostic pop
+}
+
+// CHECK: CallExpr=D:104:8 UnOp= 0
+// CHECK: CallExpr=operator++:108:3 UnOp=++ 1
+// CHECK: CallExpr=operator++:109:3 UnOp=++ 3
+// CHECK: CallExpr=operator--:110:3 UnOp=-- 2
+// CHECK: CallExpr=operator--:111:3 UnOp=-- 4
+// CHECK: CallExpr=operator&:113:3 UnOp=& 5
+// CHECK: CallExpr=operator*:112:3 UnOp=* 6
+// CHECK: CallExpr=operator+:114:3 UnOp=+ 7
+// CHECK: CallExpr=operator+:114:3 UnOp=+ 7
+// CHECK: CallExpr=operator-:115:3 UnOp=- 8
+// CHECK: CallExpr=operator-:115:3 UnOp=- 8
+// CHECK: CallExpr=operator~:117:3 UnOp=~ 9
+// CHECK: CallExpr=operator!:116:3 UnOp=! 10
+// CHECK: CallExpr=operator+:120:3 UnOp= 0
+// CHECK: CallExpr=operator-:121:3 UnOp= 0
diff --git a/clang/tools/c-index-test/c-index-test.c 
b/clang/tools/c-index-test/c-index-test.c
index 4b3e105aa7aff..6cfd42e287769 100644
--- a/clang/tools/c-index-test/c-index-test.c
+++ b/clang/tools/c-index-test/c-index-test.c
@@ -1865,7 +1865,9 @@ static enum CXChildVisitResult PrintBinOps(CXCursor C, 
CXCursor p,
   enum CXCursorKind ck = clang_getCursorKind(C);
   enum CXBinaryOperatorKind bok;
   CXString opstr;
-  if (ck != CXCursor_BinaryOperator && ck != CXCursor_CompoundAssignOperator)
+  if (ck != CXCursor_BinaryOperator && ck != CXCursor_CompoundAssignOperator &&
+      ck != CXCursor_CXXMethod && ck != CXCursor_FunctionDecl &&
+      ck != CXCursor_CallExpr)
     return CXChildVisit_Recurse;
 
   PrintCursor(C, NULL);
@@ -1876,6 +1878,22 @@ static enum CXChildVisitResult PrintBinOps(CXCursor C, 
CXCursor p,
   return CXChildVisit_Recurse;
 }
 
+static enum CXChildVisitResult PrintUnOps(CXCursor C, CXCursor p,
+                                          CXClientData d) {
+  enum CXCursorKind ck = clang_getCursorKind(C);
+  enum CXUnaryOperatorKind uok;
+  CXString opstr;
+  if (ck != CXCursor_UnaryOperator && ck != CXCursor_CXXMethod &&
+      ck != CXCursor_FunctionDecl && ck != CXCursor_CallExpr)
+    return CXChildVisit_Recurse;
+
+  PrintCursor(C, NULL);
+  uok = clang_getCursorUnaryOperatorKind(C);
+  opstr = clang_getUnaryOperatorKindSpelling(uok);
+  printf(" UnOp=%s %d\n", clang_getCString(opstr), uok);
+  clang_disposeString(opstr);
+  return CXChildVisit_Recurse;
+}
 
/******************************************************************************/
 /* Mangling testing.                                                          
*/
 
/******************************************************************************/
@@ -5177,6 +5195,8 @@ int cindextest_main(int argc, const char **argv) {
                                     PrintBitWidth, 0);
   else if (argc > 2 && strcmp(argv[1], "-test-print-binops") == 0)
     return perform_test_load_source(argc - 2, argv + 2, "all", PrintBinOps, 0);
+  else if (argc > 2 && strcmp(argv[1], "-test-print-unops") == 0)
+    return perform_test_load_source(argc - 2, argv + 2, "all", PrintUnOps, 0);
   else if (argc > 2 && strcmp(argv[1], "-test-print-mangle") == 0)
     return perform_test_load_tu(argv[2], "all", NULL, PrintMangledName, NULL);
   else if (argc > 2 && strcmp(argv[1], "-test-print-manglings") == 0)

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to