[clang-tools-extra] 647d314 - [clangd] Add support for semantic token type "operator"
Christian Kandeler via cfe-commits
cfe-commits at lists.llvm.org
Mon Dec 12 07:17:49 PST 2022
Author: Christian Kandeler
Date: 2022-12-12T16:17:43+01:00
New Revision: 647d314eb059b6d2e7c00d7eefe6a7afc37dff25
URL: https://github.com/llvm/llvm-project/commit/647d314eb059b6d2e7c00d7eefe6a7afc37dff25
DIFF: https://github.com/llvm/llvm-project/commit/647d314eb059b6d2e7c00d7eefe6a7afc37dff25.diff
LOG: [clangd] Add support for semantic token type "operator"
Also add new modifier for differentiating between built-in and user-
provided operators.
Reviewed By: sammccall
Differential Revision: https://reviews.llvm.org/D136594
Added:
Modified:
clang-tools-extra/clangd/SemanticHighlighting.cpp
clang-tools-extra/clangd/SemanticHighlighting.h
clang-tools-extra/clangd/test/initialize-params.test
clang-tools-extra/clangd/test/semantic-tokens.test
clang-tools-extra/clangd/unittests/SemanticHighlightingTests.cpp
Removed:
################################################################################
diff --git a/clang-tools-extra/clangd/SemanticHighlighting.cpp b/clang-tools-extra/clangd/SemanticHighlighting.cpp
index ccdaab89620b2..6745e2594ead3 100644
--- a/clang-tools-extra/clangd/SemanticHighlighting.cpp
+++ b/clang-tools-extra/clangd/SemanticHighlighting.cpp
@@ -566,6 +566,71 @@ class CollectExtraHighlightings
return true;
}
+ bool VisitFunctionDecl(FunctionDecl *D) {
+ if (D->isOverloadedOperator()) {
+ const auto addOpDeclToken = [&](SourceLocation Loc) {
+ auto &Token = H.addToken(Loc, HighlightingKind::Operator)
+ .addModifier(HighlightingModifier::Declaration);
+ if (D->isThisDeclarationADefinition())
+ Token.addModifier(HighlightingModifier::Definition);
+ };
+ const auto Range = D->getNameInfo().getCXXOperatorNameRange();
+ addOpDeclToken(Range.getBegin());
+ const auto Kind = D->getOverloadedOperator();
+ if (Kind == OO_Call || Kind == OO_Subscript)
+ addOpDeclToken(Range.getEnd());
+ }
+ return true;
+ }
+
+ bool VisitCXXOperatorCallExpr(CXXOperatorCallExpr *E) {
+ const auto addOpToken = [&](SourceLocation Loc) {
+ H.addToken(Loc, HighlightingKind::Operator)
+ .addModifier(HighlightingModifier::UserDefined);
+ };
+ addOpToken(E->getOperatorLoc());
+ const auto Kind = E->getOperator();
+ if (Kind == OO_Call || Kind == OO_Subscript) {
+ if (auto *Callee = E->getCallee())
+ addOpToken(Callee->getBeginLoc());
+ }
+ return true;
+ }
+
+ bool VisitUnaryOperator(UnaryOperator *Op) {
+ auto &Token = H.addToken(Op->getOperatorLoc(), HighlightingKind::Operator);
+ if (Op->getSubExpr()->isTypeDependent())
+ Token.addModifier(HighlightingModifier::UserDefined);
+ return true;
+ }
+
+ bool VisitBinaryOperator(BinaryOperator *Op) {
+ auto &Token = H.addToken(Op->getOperatorLoc(), HighlightingKind::Operator);
+ if (Op->getLHS()->isTypeDependent() || Op->getRHS()->isTypeDependent())
+ Token.addModifier(HighlightingModifier::UserDefined);
+ return true;
+ }
+
+ bool VisitConditionalOperator(ConditionalOperator *Op) {
+ H.addToken(Op->getQuestionLoc(), HighlightingKind::Operator);
+ H.addToken(Op->getColonLoc(), HighlightingKind::Operator);
+ return true;
+ }
+
+ bool VisitCXXNewExpr(CXXNewExpr *E) {
+ auto &Token = H.addToken(E->getBeginLoc(), HighlightingKind::Operator);
+ if (isa<CXXMethodDecl>(E->getOperatorNew()))
+ Token.addModifier(HighlightingModifier::UserDefined);
+ return true;
+ }
+
+ bool VisitCXXDeleteExpr(CXXDeleteExpr *E) {
+ auto &Token = H.addToken(E->getBeginLoc(), HighlightingKind::Operator);
+ if (isa<CXXMethodDecl>(E->getOperatorDelete()))
+ Token.addModifier(HighlightingModifier::UserDefined);
+ return true;
+ }
+
bool VisitCallExpr(CallExpr *E) {
// Highlighting parameters passed by non-const reference does not really
// make sense for literals...
@@ -671,12 +736,20 @@ class CollectExtraHighlightings
bool VisitCXXMemberCallExpr(CXXMemberCallExpr *CE) {
// getMethodDecl can return nullptr with member pointers, e.g.
// `(foo.*pointer_to_member_fun)(arg);`
- if (isa_and_present<CXXDestructorDecl>(CE->getMethodDecl())) {
- if (auto *ME = dyn_cast<MemberExpr>(CE->getCallee())) {
- if (auto *TI = ME->getMemberNameInfo().getNamedTypeInfo()) {
- H.addExtraModifier(TI->getTypeLoc().getBeginLoc(),
- HighlightingModifier::ConstructorOrDestructor);
+ if (auto *D = CE->getMethodDecl()) {
+ if (isa<CXXDestructorDecl>(D)) {
+ if (auto *ME = dyn_cast<MemberExpr>(CE->getCallee())) {
+ if (auto *TI = ME->getMemberNameInfo().getNamedTypeInfo()) {
+ H.addExtraModifier(TI->getTypeLoc().getBeginLoc(),
+ HighlightingModifier::ConstructorOrDestructor);
+ }
}
+ } else if (D->isOverloadedOperator()) {
+ if (auto *ME = dyn_cast<MemberExpr>(CE->getCallee()))
+ H.addToken(
+ ME->getMemberNameInfo().getCXXOperatorNameRange().getBegin(),
+ HighlightingKind::Operator)
+ .addModifier(HighlightingModifier::UserDefined);
}
}
return true;
@@ -998,6 +1071,8 @@ llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, HighlightingKind K) {
return OS << "Macro";
case HighlightingKind::Modifier:
return OS << "Modifier";
+ case HighlightingKind::Operator:
+ return OS << "Operator";
case HighlightingKind::InactiveCode:
return OS << "InactiveCode";
}
@@ -1134,6 +1209,8 @@ llvm::StringRef toSemanticTokenType(HighlightingKind Kind) {
return "macro";
case HighlightingKind::Modifier:
return "modifier";
+ case HighlightingKind::Operator:
+ return "operator";
case HighlightingKind::InactiveCode:
return "comment";
}
@@ -1168,6 +1245,8 @@ llvm::StringRef toSemanticTokenModifier(HighlightingModifier Modifier) {
return "usedAsMutablePointer"; // nonstandard
case HighlightingModifier::ConstructorOrDestructor:
return "constructorOrDestructor"; // nonstandard
+ case HighlightingModifier::UserDefined:
+ return "userDefined"; // nonstandard
case HighlightingModifier::FunctionScope:
return "functionScope"; // nonstandard
case HighlightingModifier::ClassScope:
diff --git a/clang-tools-extra/clangd/SemanticHighlighting.h b/clang-tools-extra/clangd/SemanticHighlighting.h
index e8f60c13000e1..16fde4d658dbe 100644
--- a/clang-tools-extra/clangd/SemanticHighlighting.h
+++ b/clang-tools-extra/clangd/SemanticHighlighting.h
@@ -50,6 +50,7 @@ enum class HighlightingKind {
Primitive,
Macro,
Modifier,
+ Operator,
// This one is
diff erent from the other kinds as it's a line style
// rather than a token style.
@@ -74,6 +75,7 @@ enum class HighlightingModifier {
UsedAsMutableReference,
UsedAsMutablePointer,
ConstructorOrDestructor,
+ UserDefined,
FunctionScope,
ClassScope,
diff --git a/clang-tools-extra/clangd/test/initialize-params.test b/clang-tools-extra/clangd/test/initialize-params.test
index a2df61ca75235..2afebc063d21d 100644
--- a/clang-tools-extra/clangd/test/initialize-params.test
+++ b/clang-tools-extra/clangd/test/initialize-params.test
@@ -70,6 +70,7 @@
# CHECK-NEXT: "usedAsMutableReference",
# CHECK-NEXT: "usedAsMutablePointer",
# CHECK-NEXT: "constructorOrDestructor",
+# CHECK-NEXT: "userDefined",
# CHECK-NEXT: "functionScope",
# CHECK-NEXT: "classScope",
# CHECK-NEXT: "fileScope",
diff --git a/clang-tools-extra/clangd/test/semantic-tokens.test b/clang-tools-extra/clangd/test/semantic-tokens.test
index b3a92b7cc737b..e5e8b749caeb3 100644
--- a/clang-tools-extra/clangd/test/semantic-tokens.test
+++ b/clang-tools-extra/clangd/test/semantic-tokens.test
@@ -23,7 +23,7 @@
# CHECK-NEXT: 4,
# CHECK-NEXT: 1,
# CHECK-NEXT: 0,
-# CHECK-NEXT: 65539
+# CHECK-NEXT: 131075
# CHECK-NEXT: ],
# CHECK-NEXT: "resultId": "1"
# CHECK-NEXT: }
@@ -49,7 +49,7 @@
# CHECK-NEXT: 4,
# CHECK-NEXT: 1,
# CHECK-NEXT: 0,
-# CHECK-NEXT: 65539
+# CHECK-NEXT: 131075
# CHECK-NEXT: ],
# Inserted at position 1
# CHECK-NEXT: "deleteCount": 0,
@@ -72,12 +72,12 @@
# CHECK-NEXT: 4,
# CHECK-NEXT: 1,
# CHECK-NEXT: 0,
-# CHECK-NEXT: 65539,
+# CHECK-NEXT: 131075,
# CHECK-NEXT: 1,
# CHECK-NEXT: 4,
# CHECK-NEXT: 1,
# CHECK-NEXT: 0,
-# CHECK-NEXT: 65539
+# CHECK-NEXT: 131075
# CHECK-NEXT: ],
# CHECK-NEXT: "resultId": "3"
# CHECK-NEXT: }
diff --git a/clang-tools-extra/clangd/unittests/SemanticHighlightingTests.cpp b/clang-tools-extra/clangd/unittests/SemanticHighlightingTests.cpp
index 70d8f91f129e4..de3d099986fe9 100644
--- a/clang-tools-extra/clangd/unittests/SemanticHighlightingTests.cpp
+++ b/clang-tools-extra/clangd/unittests/SemanticHighlightingTests.cpp
@@ -113,9 +113,9 @@ TEST(SemanticHighlighting, GetsCorrectTokens) {
void $Function_def[[foo]](int $Parameter_def[[A]], $Class[[AS]] $Parameter_def[[As]]) {
$Primitive_deduced_defaultLibrary[[auto]] $LocalVariable_def[[VeryLongVariableName]] = 12312;
$Class[[AS]] $LocalVariable_def[[AA]];
- $Primitive_deduced_defaultLibrary[[auto]] $LocalVariable_def[[L]] = $LocalVariable[[AA]].$Field[[SomeMember]] + $Parameter[[A]];
+ $Primitive_deduced_defaultLibrary[[auto]] $LocalVariable_def[[L]] = $LocalVariable[[AA]].$Field[[SomeMember]] $Operator[[+]] $Parameter[[A]];
auto $LocalVariable_def[[FN]] = [ $LocalVariable[[AA]]](int $Parameter_def[[A]]) -> void {};
- $LocalVariable[[FN]](12312);
+ $LocalVariable[[FN]]$Operator_userDefined[[(]]12312$Operator_userDefined[[)]];
}
)cpp",
R"cpp(
@@ -144,7 +144,7 @@ TEST(SemanticHighlighting, GetsCorrectTokens) {
struct $Class_def[[B]] {
$Class_decl_constrDestr[[B]]();
~$Class_decl_constrDestr[[B]]();
- void operator<<($Class[[B]]);
+ void operator$Operator_decl[[<<]]($Class[[B]]);
$Class[[AAA]] $Field_decl[[AA]];
};
$Class[[B]]::$Class_def_constrDestr[[B]]() {}
@@ -203,20 +203,20 @@ TEST(SemanticHighlighting, GetsCorrectTokens) {
static double $StaticField_decl_static[[S]];
static void $StaticMethod_def_static[[bar]]() {}
void $Method_def[[foo]]() {
- $Field[[B]] = 123;
- this->$Field[[B]] = 156;
+ $Field[[B]] $Operator[[=]] 123;
+ this->$Field[[B]] $Operator[[=]] 156;
this->$Method[[foo]]();
$Method[[foo]]();
$StaticMethod_static[[bar]]();
- $StaticField_static[[S]] = 90.1;
+ $StaticField_static[[S]] $Operator[[=]] 90.1;
}
};
void $Function_def[[foo]]() {
$Class[[A]] $LocalVariable_def[[AA]];
- $LocalVariable[[AA]].$Field[[B]] += 2;
+ $LocalVariable[[AA]].$Field[[B]] $Operator[[+=]] 2;
$LocalVariable[[AA]].$Method[[foo]]();
$LocalVariable[[AA]].$Field[[E]].$Field[[C]];
- $Class[[A]]::$StaticField_static[[S]] = 90;
+ $Class[[A]]::$StaticField_static[[S]] $Operator[[=]] 90;
}
)cpp",
R"cpp(
@@ -295,10 +295,10 @@ TEST(SemanticHighlighting, GetsCorrectTokens) {
struct $Class_def[[B]] {};
struct $Class_def[[A]] {
$Class[[B]] $Field_decl[[BB]];
- $Class[[A]] &operator=($Class[[A]] &&$Parameter_def[[O]]);
+ $Class[[A]] &operator$Operator_decl[[=]]($Class[[A]] &&$Parameter_def[[O]]);
};
- $Class[[A]] &$Class[[A]]::operator=($Class[[A]] &&$Parameter_def[[O]]) = default;
+ $Class[[A]] &$Class[[A]]::operator$Operator_def[[=]]($Class[[A]] &&$Parameter_def[[O]]) = default;
)cpp",
R"cpp(
enum $Enum_decl[[En]] {
@@ -327,9 +327,9 @@ TEST(SemanticHighlighting, GetsCorrectTokens) {
$Enum_deduced[[auto]] $Variable_def[[AE]] = $Enum[[E]]::$EnumConstant_readonly[[E]];
$Class_deduced[[auto]] $Variable_def[[AF]] = $Class[[Foo]]();
$Class_deduced[[decltype]](auto) $Variable_def[[AF2]] = $Class[[Foo]]();
- $Class_deduced[[auto]] *$Variable_def[[AFP]] = &$Variable[[AF]];
+ $Class_deduced[[auto]] *$Variable_def[[AFP]] = $Operator[[&]]$Variable[[AF]];
$Enum_deduced[[auto]] &$Variable_def[[AER]] = $Variable[[AE]];
- $Primitive_deduced_defaultLibrary[[auto]] $Variable_def[[Form]] = 10.2 + 2 * 4;
+ $Primitive_deduced_defaultLibrary[[auto]] $Variable_def[[Form]] = 10.2 $Operator[[+]] 2 $Operator[[*]] 4;
$Primitive_deduced_defaultLibrary[[decltype]]($Variable[[Form]]) $Variable_def[[F]] = 10;
auto $Variable_def[[Fun]] = []()->void{};
)cpp",
@@ -342,21 +342,21 @@ TEST(SemanticHighlighting, GetsCorrectTokens) {
template<int *$TemplateParameter_def_readonly[[U]]>
class $Class_def[[IP]] {
void $Method_def[[f]]() {
- *$TemplateParameter_readonly[[U]] += 5;
+ $Operator[[*]]$TemplateParameter_readonly[[U]] $Operator[[+=]] 5;
}
};
template<unsigned $TemplateParameter_def_readonly[[U]] = 2>
class $Class_def[[Foo]] {
void $Method_def[[f]]() {
for(int $LocalVariable_def[[I]] = 0;
- $LocalVariable[[I]] < $TemplateParameter_readonly[[U]];) {}
+ $LocalVariable[[I]] $Operator[[<]] $TemplateParameter_readonly[[U]];) {}
}
};
$Class[[G]] $Variable_def[[L]];
void $Function_def[[f]]() {
$Class[[Foo]]<123> $LocalVariable_def[[F]];
- $Class[[GP]]<&$Variable[[L]]> $LocalVariable_def[[LL]];
+ $Class[[GP]]<$Operator[[&]]$Variable[[L]]> $LocalVariable_def[[LL]];
$Class[[GR]]<$Variable[[L]]> $LocalVariable_def[[LLL]];
}
)cpp",
@@ -366,7 +366,8 @@ TEST(SemanticHighlighting, GetsCorrectTokens) {
struct $Class_def[[G]] {
void $Method_def[[foo]](
$TemplateParameter[[T]] *$Parameter_def[[O]]) {
- ($Parameter[[O]]->*$TemplateParameter_readonly[[method]])(10);
+ ($Parameter[[O]]$Operator_userDefined[[->*]]$TemplateParameter_readonly[[method]])(10);
+
}
};
struct $Class_def[[F]] {
@@ -375,14 +376,14 @@ TEST(SemanticHighlighting, GetsCorrectTokens) {
template<void (*$TemplateParameter_def_readonly[[Func]])()>
struct $Class_def[[A]] {
void $Method_def[[f]]() {
- (*$TemplateParameter_readonly[[Func]])();
+ ($Operator[[*]]$TemplateParameter_readonly[[Func]])();
}
};
void $Function_def[[foo]]() {
$Class[[F]] $LocalVariable_def[[FF]];
- $Class[[G]]<$Class[[F]], &$Class[[F]]::$Method[[f]]> $LocalVariable_def[[GG]];
- $LocalVariable[[GG]].$Method[[foo]](&$LocalVariable_usedAsMutablePointer[[FF]]);
+ $Class[[G]]<$Class[[F]], $Operator[[&]]$Class[[F]]::$Method[[f]]> $LocalVariable_def[[GG]];
+ $LocalVariable[[GG]].$Method[[foo]]($Operator[[&]]$LocalVariable_usedAsMutablePointer[[FF]]);
$Class[[A]]<$Function[[foo]]> $LocalVariable_def[[AA]];
}
)cpp",
@@ -411,7 +412,7 @@ TEST(SemanticHighlighting, GetsCorrectTokens) {
$Macro[[DEF_VAR_TYPE]]($Class[[A]], $LocalVariable_def[[AA]]);
double $Macro[[SOME_NAME]];
int $Macro[[SOME_NAME_SET]];
- $LocalVariable[[variable]] = 20.1;
+ $LocalVariable[[variable]] $Operator[[=]] 20.1;
$Macro[[MACRO_CONCAT]](var, 2, float);
$Macro[[DEF_VAR_T]]($Class[[A]], $Macro[[CPY]](
$Macro[[CPY]]($LocalVariable_def[[Nested]])),
@@ -436,8 +437,8 @@ TEST(SemanticHighlighting, GetsCorrectTokens) {
int $Variable_def[[y]];
int $Function_decl[[f]]();
void $Function_def[[foo]]() {
- $Macro[[assert]]($Variable[[x]] != $Variable[[y]]);
- $Macro[[assert]]($Variable[[x]] != $Function[[f]]());
+ $Macro[[assert]]($Variable[[x]] $Operator[[!=]] $Variable[[y]]);
+ $Macro[[assert]]($Variable[[x]] $Operator[[!=]] $Function[[f]]());
}
)cpp",
// highlighting all macro references
@@ -467,7 +468,7 @@ TEST(SemanticHighlighting, GetsCorrectTokens) {
auto [$LocalVariable_decl[[G1]], $LocalVariable_decl[[G2]]] = $Variable[[Global]];
$Class_deduced[[auto]] [$LocalVariable_decl[[P1]], $LocalVariable_decl[[P2]]] = $Parameter[[P]];
// Highlights references to BindingDecls.
- $LocalVariable[[B1]]++;
+ $LocalVariable[[B1]]$Operator[[++]];
}
)cpp",
R"cpp(
@@ -724,9 +725,9 @@ sizeof...($TemplateParameter[[Elements]]);
return 0;
}
- (int)$Method_def[[doSomething]] {
- $Class[[Foo]].$Field_static[[sharedInstance]].$Field[[someProperty]] = 1;
- self.$Field[[someProperty]] = self.$Field[[someProperty]] + self.$Field[[otherMethod]] + 1;
- self->$Field[[_someProperty]] = $Field[[_someProperty]] + 1;
+ $Class[[Foo]].$Field_static[[sharedInstance]].$Field[[someProperty]] $Operator[[=]] 1;
+ self.$Field[[someProperty]] $Operator[[=]] self.$Field[[someProperty]] $Operator[[+]] self.$Field[[otherMethod]] $Operator[[+]] 1;
+ self->$Field[[_someProperty]] $Operator[[=]] $Field[[_someProperty]] $Operator[[+]] 1;
}
@end
)cpp",
@@ -747,11 +748,11 @@ sizeof...($TemplateParameter[[Elements]]);
// Modifier for variables passed as non-const references
R"cpp(
struct $Class_def[[ClassWithOp]] {
- void operator()(int);
- void operator()(int, int &);
- void operator()(int, int, const int &);
- int &operator[](int &);
- int operator[](int) const;
+ void operator$Operator_decl[[(]]$Operator_decl[[)]](int);
+ void operator$Operator_decl[[(]]$Operator_decl[[)]](int, int &);
+ void operator$Operator_decl[[(]]$Operator_decl[[)]](int, int, const int &);
+ int &operator$Operator_decl[[[]]$Operator_decl[[]]](int &);
+ int operator$Operator_decl[[[]]$Operator_decl[[]]](int) const;
};
struct $Class_def[[ClassWithStaticMember]] {
static inline int $StaticField_def_static[[j]] = 0;
@@ -791,16 +792,16 @@ sizeof...($TemplateParameter[[Elements]]);
$LocalVariable_usedAsMutablePointer[[array]], $LocalVariable_usedAsMutableReference[[array]],
$LocalVariable[[array]]
);
- [](int){}($LocalVariable[[val]]);
- [](int&){}($LocalVariable_usedAsMutableReference[[val]]);
- [](const int&){}($LocalVariable[[val]]);
+ [](int){}$Operator_userDefined[[(]]$LocalVariable[[val]]$Operator_userDefined[[)]];
+ [](int&){}$Operator_userDefined[[(]]$LocalVariable_usedAsMutableReference[[val]]$Operator_userDefined[[)]];
+ [](const int&){}$Operator_userDefined[[(]]$LocalVariable[[val]]$Operator_userDefined[[)]];
$Class[[ClassWithOp]] $LocalVariable_def[[c]];
const $Class[[ClassWithOp]] $LocalVariable_def_readonly[[c2]];
- $LocalVariable[[c]]($LocalVariable[[val]]);
- $LocalVariable[[c]](0, $LocalVariable_usedAsMutableReference[[val]]);
- $LocalVariable[[c]](0, 0, $LocalVariable[[val]]);
- $LocalVariable[[c]][$LocalVariable_usedAsMutableReference[[val]]];
- $LocalVariable_readonly[[c2]][$LocalVariable[[val]]];
+ $LocalVariable[[c]]$Operator_userDefined[[(]]$LocalVariable[[val]]$Operator_userDefined[[)]];
+ $LocalVariable[[c]]$Operator_userDefined[[(]]0, $LocalVariable_usedAsMutableReference[[val]]$Operator_userDefined[[)]];
+ $LocalVariable[[c]]$Operator_userDefined[[(]]0, 0, $LocalVariable[[val]]$Operator_userDefined[[)]];
+ $LocalVariable[[c]]$Operator_userDefined[[[]]$LocalVariable_usedAsMutableReference[[val]]$Operator_userDefined[[]]];
+ $LocalVariable_readonly[[c2]]$Operator_userDefined[[[]]$LocalVariable[[val]]$Operator_userDefined[[]]];
}
struct $Class_def[[S]] {
$Class_def_constrDestr[[S]](int&) {
@@ -824,7 +825,7 @@ sizeof...($TemplateParameter[[Elements]]);
void $Function_def[[foo]]() {
int $LocalVariable_def[[a]], $LocalVariable_def[[b]];
[ $LocalVariable_def[[c]] = $LocalVariable[[a]],
- $LocalVariable_def[[d]]($LocalVariable[[b]]) ]() {}();
+ $LocalVariable_def[[d]]($LocalVariable[[b]]) ]() {}$Operator_userDefined[[(]]$Operator_userDefined[[)]];
}
)cpp",
// Enum base specifier
@@ -877,8 +878,8 @@ sizeof...($TemplateParameter[[Elements]]);
const $TemplateParameter[[auto]] $Parameter_def_readonly[[auto_type]],
const int $Parameter_def_readonly[[explicit_type]]) {
return $Parameter_readonly[[template_type]]
- + $Parameter_readonly[[auto_type]]
- + $Parameter_readonly[[explicit_type]];
+ $Operator_userDefined[[+]] $Parameter_readonly[[auto_type]]
+ $Operator_userDefined[[+]] $Parameter_readonly[[explicit_type]];
}
)cpp",
// Explicit template specialization
@@ -894,6 +895,33 @@ sizeof...($TemplateParameter[[Elements]]);
template <>
int $Variable_def[[x]]<int> = (int)sizeof($Class[[Base]]);
)cpp",
+ // operator calls in template
+ R"cpp(
+ template<typename $TemplateParameter_def[[T]]> class $Class_def[[C]] {
+ bool $Method_def[[compare]]($TemplateParameter[[T]] $Parameter_def[[t1]], $TemplateParameter[[T]] $Parameter_def[[t2]]) { return $Parameter[[t1]] $Operator_userDefined[[==]] $Parameter[[t2]]; }
+ $TemplateParameter[[T]] $Method_def[[deref]]($TemplateParameter[[T]] *$Parameter_def[[t]]) { return $Operator_userDefined[[*]]$Parameter[[t]]; }
+ };
+ )cpp",
+ // new and delete
+ R"cpp(
+ struct $Class_def[[S]] { int *$Field_decl[[a]]; };
+ void $Function_def[[f]]() {
+ $Class[[S]] *$LocalVariable_def[[s]] = $Operator[[new]] $Class[[S]];
+ $LocalVariable[[s]]->$Field[[a]] $Operator[[=]] $Operator[[new]] int[10];
+ $Operator[[delete]][] $LocalVariable[[s]]->$Field[[a]];
+ $Operator[[delete]] $LocalVariable[[s]];
+ }
+ )cpp",
+ // explicit operator invocation
+ R"cpp(
+ struct $Class_def[[S]] {
+ $Class[[S]] operator$Operator_decl[[+]](const $Class[[S]] &$Parameter_def_readonly[[other]]);
+ };
+ void $Function_def[[f]]() {
+ $Class[[S]] $LocalVariable_def[[s]];
+ $Class[[S]] $LocalVariable_def[[s2]] = $LocalVariable[[s]].operator$Operator_userDefined[[+]]($LocalVariable[[s]]);
+ }
+ )cpp",
// no crash
R"cpp(
struct $Class_def[[Foo]] {
@@ -901,8 +929,8 @@ sizeof...($TemplateParameter[[Elements]]);
};
void $Function_def[[s]]($Class[[Foo]] $Parameter_def[[f]]) {
- auto $LocalVariable_def[[k]] = &$Class[[Foo]]::$Method[[foo]];
- ($Parameter[[f]].*$LocalVariable[[k]])(); // no crash on VisitCXXMemberCallExpr
+ auto $LocalVariable_def[[k]] = $Operator[[&]]$Class[[Foo]]::$Method[[foo]];
+ ($Parameter[[f]]$Operator[[.*]]$LocalVariable[[k]])(); // no crash on VisitCXXMemberCallExpr
}
)cpp"};
for (const auto &TestCase : TestCases)
@@ -942,7 +970,7 @@ sizeof...($TemplateParameter[[Elements]]);
@end
int $Function_def[[somethingUsingSystemSymbols]]() {
$Class_defaultLibrary[[SYSObject]] *$LocalVariable_def[[obj]] = [$Class_defaultLibrary[[SYSObject]] $StaticMethod_static_defaultLibrary[[new]]];
- return $LocalVariable[[obj]].$Field_defaultLibrary[[value]] + $LocalVariable[[obj]].$Field_readonly[[user_property]];
+ return $LocalVariable[[obj]].$Field_defaultLibrary[[value]] $Operator[[+]] $LocalVariable[[obj]].$Field_readonly[[user_property]];
}
)cpp",
{{"SystemSDK/SYSObject.h", R"cpp(
More information about the cfe-commits
mailing list