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 6300718233206b5d4798a079d12545d71745fedd 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 | 437 +++++++++++++++++++++++- clang/test/Index/unop.cpp | 175 ++++++++++ clang/tools/c-index-test/c-index-test.c | 22 +- 3 files changed, 632 insertions(+), 2 deletions(-) create mode 100644 clang/test/Index/unop.cpp diff --git a/clang/test/Index/binop.cpp b/clang/test/Index/binop.cpp index 576fd73cc2abf..743a0279a896f 100644 --- a/clang/test/Index/binop.cpp +++ b/clang/test/Index/binop.cpp @@ -1,4 +1,4 @@ -// RUN: c-index-test -test-print-binops %s | FileCheck %s +// RUN: c-index-test -test-print-binops -std=c++20 %s | FileCheck %s struct C { int m; @@ -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
