760 lines · cpp
1//===-- OverridePureVirtualsTests.cpp ---------------------------*- C++ -*-===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#include "TweakTesting.h"10#include "gtest/gtest.h"11 12namespace clang {13namespace clangd {14namespace {15 16class OverridePureVirtualsTests : public TweakTest {17protected:18 OverridePureVirtualsTests() : TweakTest("OverridePureVirtuals") {}19};20 21TEST_F(OverridePureVirtualsTests, MinimalUnavailable) {22 EXPECT_UNAVAILABLE("class ^C {};");23}24 25TEST_F(OverridePureVirtualsTests, MinimalAvailable) {26 EXPECT_AVAILABLE(R"cpp(27class B { public: virtual void Foo() = 0; };28class ^C : public B {};29)cpp");30}31 32TEST_F(OverridePureVirtualsTests, UnavailableWhenOverriden) {33 EXPECT_UNAVAILABLE(34 R"cpp(35class B {36public:37 virtual void foo() = 0;38};39 40class ^D : public B {41public:42 void foo() override;43};44)cpp");45}46 47TEST_F(OverridePureVirtualsTests, AvailabilityNoOverride) {48 EXPECT_AVAILABLE(R"cpp(49class Base {50public:51virtual ~Base() = default;52virtual void F1() = 0;53virtual void F2() = 0;54};55 56class ^Derived : public Base {57public:58};59 60)cpp");61}62 63TEST_F(OverridePureVirtualsTests, AvailabilityPartiallyOverridden) {64 EXPECT_AVAILABLE(R"cpp(65class Base {66public:67virtual ~Base() = default;68virtual void F1() = 0;69virtual void F2() = 0;70};71 72class ^Derived : public Base {73public:74void F1() override;75};76)cpp");77}78 79TEST_F(OverridePureVirtualsTests, EmptyDerivedClass) {80 const char *Before = R"cpp(81class Base {82public:83virtual ~Base() = default;84virtual void F1() = 0;85virtual void F2(int P1, const int &P2) = 0;86};87 88class ^Derived : public Base {};89)cpp";90 const auto *Expected = R"cpp(91class Base {92public:93virtual ~Base() = default;94virtual void F1() = 0;95virtual void F2(int P1, const int &P2) = 0;96};97 98class Derived : public Base {99public:100 void F1() override {101 // TODO: Implement this pure virtual method.102 static_assert(false, "Method `F1` is not implemented.");103 }104 105 void F2(int P1, const int & P2) override {106 // TODO: Implement this pure virtual method.107 static_assert(false, "Method `F2` is not implemented.");108 }109};110)cpp";111 auto Applied = apply(Before);112 EXPECT_EQ(Expected, Applied) << "Applied result:\n" << Applied;113}114 115TEST_F(OverridePureVirtualsTests, SingleBaseClassPartiallyImplemented) {116 auto Applied = apply(117 R"cpp(118class Base {119public:120virtual ~Base() = default;121virtual void F1() = 0;122virtual void F2() = 0;123};124 125class ^Derived : public Base {126public:127 void F1() override;128};129)cpp");130 131 const auto *Expected = R"cpp(132class Base {133public:134virtual ~Base() = default;135virtual void F1() = 0;136virtual void F2() = 0;137};138 139class Derived : public Base {140public:141 void F2() override {142 // TODO: Implement this pure virtual method.143 static_assert(false, "Method `F2` is not implemented.");144 }145 146 void F1() override;147};148)cpp";149 EXPECT_EQ(Applied, Expected) << "Applied result:\n" << Applied;150}151 152TEST_F(OverridePureVirtualsTests, MultipleDirectBaseClasses) {153 const char *Before = R"cpp(154class Base1 {155public:156 virtual void func1() = 0;157};158class Base2 {159protected:160 virtual bool func2(char c) const = 0;161};162 163class ^Derived : public Base1, public Base2 {};164)cpp";165 const auto *Expected = R"cpp(166class Base1 {167public:168 virtual void func1() = 0;169};170class Base2 {171protected:172 virtual bool func2(char c) const = 0;173};174 175class Derived : public Base1, public Base2 {176public:177 void func1() override {178 // TODO: Implement this pure virtual method.179 static_assert(false, "Method `func1` is not implemented.");180 }181protected:182 bool func2(char c) const override {183 // TODO: Implement this pure virtual method.184 static_assert(false, "Method `func2` is not implemented.");185 }186};187)cpp";188 auto Applied = apply(Before);189 EXPECT_EQ(Expected, Applied) << "Applied result:\n" << Applied;190}191 192TEST_F(OverridePureVirtualsTests, UnnamedParametersInBase) {193 const char *Before = R"cpp(194struct S {};195class Base {196public:197 virtual void func(int, const S&, char*) = 0;198};199 200class ^Derived : public Base {};201)cpp";202 203 const auto *Expected = R"cpp(204struct S {};205class Base {206public:207 virtual void func(int, const S&, char*) = 0;208};209 210class Derived : public Base {211public:212 void func(int, const S &, char *) override {213 // TODO: Implement this pure virtual method.214 static_assert(false, "Method `func` is not implemented.");215 }216};217)cpp";218 auto Applied = apply(Before);219 EXPECT_EQ(Expected, Applied) << "Applied result:\n" << Applied;220}221 222TEST_F(OverridePureVirtualsTests, DiamondInheritance) {223 const char *Before = R"cpp(224class Top {225public:226 virtual ~Top() = default;227 virtual void diamond_func() = 0;228};229class Left : virtual public Top {};230class Right : virtual public Top {};231class ^Bottom : public Left, public Right {};232)cpp";233 const auto *Expected = R"cpp(234class Top {235public:236 virtual ~Top() = default;237 virtual void diamond_func() = 0;238};239class Left : virtual public Top {};240class Right : virtual public Top {};241class Bottom : public Left, public Right {242public:243 void diamond_func() override {244 // TODO: Implement this pure virtual method.245 static_assert(false, "Method `diamond_func` is not implemented.");246 }247};248)cpp";249 auto Applied = apply(Before);250 EXPECT_EQ(Expected, Applied) << "Applied result:\n" << Applied;251}252 253TEST_F(OverridePureVirtualsTests, MixedAccessSpecifiers) {254 const char *Before = R"cpp(255class Base {256public:257 virtual void pub_func() = 0;258 virtual void pub_func2(char) const = 0;259protected:260 virtual int prot_func(int x) const = 0;261};262 263class ^Derived : public Base {264 int member; // Existing member265public:266 Derived(int m) : member(m) {}267};268)cpp";269 const auto *Expected = R"cpp(270class Base {271public:272 virtual void pub_func() = 0;273 virtual void pub_func2(char) const = 0;274protected:275 virtual int prot_func(int x) const = 0;276};277 278class Derived : public Base {279 int member; // Existing member280public:281 void pub_func() override {282 // TODO: Implement this pure virtual method.283 static_assert(false, "Method `pub_func` is not implemented.");284 }285 286 void pub_func2(char) const override {287 // TODO: Implement this pure virtual method.288 static_assert(false, "Method `pub_func2` is not implemented.");289 }290 291 Derived(int m) : member(m) {}292 293protected:294 int prot_func(int x) const override {295 // TODO: Implement this pure virtual method.296 static_assert(false, "Method `prot_func` is not implemented.");297 }298};299)cpp";300 auto Applied = apply(Before);301 EXPECT_EQ(Expected, Applied) << "Applied result:\n" << Applied;302}303 304TEST_F(OverridePureVirtualsTests, OutOfOrderMixedAccessSpecifiers) {305 const char *Before = R"cpp(306class Base {307public:308 virtual void pub_func() = 0;309 virtual void pub_func2(char) const = 0;310protected:311 virtual int prot_func(int x) const = 0;312};313 314class ^Derived : public Base {315 int member; // Existing member316protected:317 void foo();318public:319 Derived(int m) : member(m) {}320};321)cpp";322 const auto *Expected = R"cpp(323class Base {324public:325 virtual void pub_func() = 0;326 virtual void pub_func2(char) const = 0;327protected:328 virtual int prot_func(int x) const = 0;329};330 331class Derived : public Base {332 int member; // Existing member333protected:334 int prot_func(int x) const override {335 // TODO: Implement this pure virtual method.336 static_assert(false, "Method `prot_func` is not implemented.");337 }338 339 void foo();340public:341 void pub_func() override {342 // TODO: Implement this pure virtual method.343 static_assert(false, "Method `pub_func` is not implemented.");344 }345 346 void pub_func2(char) const override {347 // TODO: Implement this pure virtual method.348 static_assert(false, "Method `pub_func2` is not implemented.");349 }350 351 Derived(int m) : member(m) {}352};353)cpp";354 auto Applied = apply(Before);355 EXPECT_EQ(Expected, Applied) << "Applied result:\n" << Applied;356}357 358TEST_F(OverridePureVirtualsTests, MultiAccessSpecifiersOverride) {359 constexpr auto Before = R"cpp(360class Base {361public:362 virtual void foo() = 0;363protected:364 virtual void bar() = 0;365};366 367class ^Derived : public Base {};368)cpp";369 370 constexpr auto Expected = R"cpp(371class Base {372public:373 virtual void foo() = 0;374protected:375 virtual void bar() = 0;376};377 378class Derived : public Base {379public:380 void foo() override {381 // TODO: Implement this pure virtual method.382 static_assert(false, "Method `foo` is not implemented.");383 }384protected:385 void bar() override {386 // TODO: Implement this pure virtual method.387 static_assert(false, "Method `bar` is not implemented.");388 }389};390)cpp";391 auto Applied = apply(Before);392 EXPECT_EQ(Expected, Applied) << "Applied result:\n" << Applied;393}394 395TEST_F(OverridePureVirtualsTests, AccessSpecifierAlreadyExisting) {396 const char *Before = R"cpp(397class Base {398public:399 virtual void func1() = 0;400};401 402class ^Derived : public Base {403public:404};405)cpp";406 407 const auto *Expected = R"cpp(408class Base {409public:410 virtual void func1() = 0;411};412 413class Derived : public Base {414public:415 void func1() override {416 // TODO: Implement this pure virtual method.417 static_assert(false, "Method `func1` is not implemented.");418 }419 420};421)cpp";422 auto Applied = apply(Before);423 EXPECT_EQ(Expected, Applied) << "Applied result:\n" << Applied;424}425 426TEST_F(OverridePureVirtualsTests, ConstexprSpecifier) {427 ExtraArgs.push_back("-std=c++20");428 429 constexpr auto Before = R"cpp(430class B {431public:432 constexpr virtual int getValue() const = 0;433};434 435class ^D : public B {};436)cpp";437 438 constexpr auto Expected = R"cpp(439class B {440public:441 constexpr virtual int getValue() const = 0;442};443 444class D : public B {445public:446 constexpr int getValue() const override {447 // TODO: Implement this pure virtual method.448 static_assert(false, "Method `getValue` is not implemented.");449 }450};451)cpp";452 auto Applied = apply(Before);453 EXPECT_EQ(Expected, Applied) << "Applied result:\n" << Applied;454}455 456TEST_F(OverridePureVirtualsTests, ConstevalSpecifier) {457 ExtraArgs.push_back("-std=c++20");458 459 constexpr auto Before = R"cpp(460class B {461public:462 virtual consteval float calculate() = 0;463};464 465class ^D : public B {};466)cpp";467 468 constexpr auto Expected = R"cpp(469class B {470public:471 virtual consteval float calculate() = 0;472};473 474class D : public B {475public:476 consteval float calculate() override {477 // TODO: Implement this pure virtual method.478 static_assert(false, "Method `calculate` is not implemented.");479 }480};481)cpp";482 auto Applied = apply(Before);483 EXPECT_EQ(Expected, Applied) << "Applied result:\n" << Applied;484}485 486TEST_F(OverridePureVirtualsTests, LValueRefQualifier) {487 constexpr auto Before = R"cpp(488class B {489public:490 virtual void process() & = 0;491};492 493class ^D : public B {};494)cpp";495 496 constexpr auto Expected = R"cpp(497class B {498public:499 virtual void process() & = 0;500};501 502class D : public B {503public:504 void process() & override {505 // TODO: Implement this pure virtual method.506 static_assert(false, "Method `process` is not implemented.");507 }508};509)cpp";510 auto Applied = apply(Before);511 EXPECT_EQ(Expected, Applied) << "Applied result:\n" << Applied;512}513 514TEST_F(OverridePureVirtualsTests, RValueRefQualifier) {515 constexpr auto Before = R"cpp(516class B {517public:518 virtual bool isValid() && = 0;519};520 521class ^D : public B {};522)cpp";523 524 constexpr auto Expected = R"cpp(525class B {526public:527 virtual bool isValid() && = 0;528};529 530class D : public B {531public:532 bool isValid() && override {533 // TODO: Implement this pure virtual method.534 static_assert(false, "Method `isValid` is not implemented.");535 }536};537)cpp";538 auto Applied = apply(Before);539 EXPECT_EQ(Expected, Applied) << "Applied result:\n" << Applied;540}541 542TEST_F(OverridePureVirtualsTests, SimpleTrailingReturnType) {543 constexpr auto Before = R"cpp(544class B {545public:546 virtual auto getStatus() -> bool = 0;547};548 549class ^D : public B {};550)cpp";551 552 constexpr auto Expected = R"cpp(553class B {554public:555 virtual auto getStatus() -> bool = 0;556};557 558class D : public B {559public:560 auto getStatus() -> bool override {561 // TODO: Implement this pure virtual method.562 static_assert(false, "Method `getStatus` is not implemented.");563 }564};565)cpp";566 auto Applied = apply(Before);567 EXPECT_EQ(Expected, Applied) << "Applied result:\n" << Applied;568}569 570TEST_F(OverridePureVirtualsTests, ConstexprLValueRefAndTrailingReturn) {571 ExtraArgs.push_back("-std=c++20");572 573 constexpr auto Before = R"cpp(574class B {575public:576 constexpr virtual auto getData() & -> const char * = 0;577};578 579class ^D : public B {};580)cpp";581 582 constexpr auto Expected = R"cpp(583class B {584public:585 constexpr virtual auto getData() & -> const char * = 0;586};587 588class D : public B {589public:590 constexpr auto getData() & -> const char * override {591 // TODO: Implement this pure virtual method.592 static_assert(false, "Method `getData` is not implemented.");593 }594};595)cpp";596 auto Applied = apply(Before);597 EXPECT_EQ(Expected, Applied) << "Applied result:\n" << Applied;598}599 600TEST_F(OverridePureVirtualsTests, ConstevalRValueRefAndTrailingReturn) {601 ExtraArgs.push_back("-std=c++20");602 603 constexpr auto Before = R"cpp(604class B {605public:606 virtual consteval auto foo() && -> double = 0;607};608 609class ^D : public B {};610)cpp";611 612 constexpr auto Expected = R"cpp(613class B {614public:615 virtual consteval auto foo() && -> double = 0;616};617 618class D : public B {619public:620 consteval auto foo() && -> double override {621 // TODO: Implement this pure virtual method.622 static_assert(false, "Method `foo` is not implemented.");623 }624};625)cpp";626 auto Applied = apply(Before);627 EXPECT_EQ(Expected, Applied) << "Applied result:\n" << Applied;628}629 630TEST_F(OverridePureVirtualsTests, CombinedFeaturesWithTrailingReturnTypes) {631 ExtraArgs.push_back("-std=c++20");632 633 constexpr auto Before = R"cpp(634class B {635public:636 virtual auto f1() & -> int = 0;637 constexpr virtual auto f2() && -> int = 0;638 virtual consteval auto f3() -> int = 0;639 virtual auto f4() const & -> char = 0;640 constexpr virtual auto f5() const && -> bool = 0;641};642 643class ^D : public B {};644)cpp";645 646 constexpr auto Expected = R"cpp(647class B {648public:649 virtual auto f1() & -> int = 0;650 constexpr virtual auto f2() && -> int = 0;651 virtual consteval auto f3() -> int = 0;652 virtual auto f4() const & -> char = 0;653 constexpr virtual auto f5() const && -> bool = 0;654};655 656class D : public B {657public:658 auto f1() & -> int override {659 // TODO: Implement this pure virtual method.660 static_assert(false, "Method `f1` is not implemented.");661 }662 663 constexpr auto f2() && -> int override {664 // TODO: Implement this pure virtual method.665 static_assert(false, "Method `f2` is not implemented.");666 }667 668 consteval auto f3() -> int override {669 // TODO: Implement this pure virtual method.670 static_assert(false, "Method `f3` is not implemented.");671 }672 673 auto f4() const & -> char override {674 // TODO: Implement this pure virtual method.675 static_assert(false, "Method `f4` is not implemented.");676 }677 678 constexpr auto f5() const && -> bool override {679 // TODO: Implement this pure virtual method.680 static_assert(false, "Method `f5` is not implemented.");681 }682};683)cpp";684 auto Applied = apply(Before);685 EXPECT_EQ(Expected, Applied) << "Applied result:\n" << Applied;686}687 688TEST_F(OverridePureVirtualsTests, DefaultParameters) {689 ExtraArgs.push_back("-std=c++20");690 691 constexpr auto Before = R"cpp(692class B {693public:694 virtual void foo(int var = 0) = 0;695};696 697class ^D : public B {};698)cpp";699 700 constexpr auto Expected = R"cpp(701class B {702public:703 virtual void foo(int var = 0) = 0;704};705 706class D : public B {707public:708 void foo(int var = 0) override {709 // TODO: Implement this pure virtual method.710 static_assert(false, "Method `foo` is not implemented.");711 }712};713)cpp";714 auto Applied = apply(Before);715 EXPECT_EQ(Expected, Applied) << "Applied result:\n" << Applied;716}717 718TEST_F(OverridePureVirtualsTests, QualifiedNames) {719 constexpr auto Before = R"cpp(720namespace foo { struct S{}; namespace bar { struct S2{}; } }721 722class B {723public:724 virtual foo::S foo(int var = 0) = 0;725 virtual foo::bar::S2 bar(int var = 0) = 0;726};727 728class ^D : public B {};729)cpp";730 731 constexpr auto Expected = R"cpp(732namespace foo { struct S{}; namespace bar { struct S2{}; } }733 734class B {735public:736 virtual foo::S foo(int var = 0) = 0;737 virtual foo::bar::S2 bar(int var = 0) = 0;738};739 740class D : public B {741public:742 foo::S foo(int var = 0) override {743 // TODO: Implement this pure virtual method.744 static_assert(false, "Method `foo` is not implemented.");745 }746 747 foo::bar::S2 bar(int var = 0) override {748 // TODO: Implement this pure virtual method.749 static_assert(false, "Method `bar` is not implemented.");750 }751};752)cpp";753 auto Applied = apply(Before);754 EXPECT_EQ(Expected, Applied) << "Applied result:\n" << Applied;755}756 757} // namespace758} // namespace clangd759} // namespace clang760