File: MemberwiseConstructorTests.cpp

package info (click to toggle)
llvm-toolchain-19 1%3A19.1.7-3~deb12u1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm-proposed-updates
  • size: 1,998,492 kB
  • sloc: cpp: 6,951,680; ansic: 1,486,157; asm: 913,598; python: 232,024; f90: 80,126; objc: 75,281; lisp: 37,276; pascal: 16,990; sh: 10,009; ml: 5,058; perl: 4,724; awk: 3,523; makefile: 3,167; javascript: 2,504; xml: 892; fortran: 664; cs: 573
file content (101 lines) | stat: -rw-r--r-- 3,303 bytes parent folder | download | duplicates (13)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
//===-- MemberwiseConstructorTests.cpp ------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "TweakTesting.h"
#include "gmock/gmock-matchers.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"

namespace clang {
namespace clangd {
namespace {
using testing::AllOf;
using testing::Eq;
using testing::HasSubstr;
using testing::Not;

TWEAK_TEST(MemberwiseConstructor);

TEST_F(MemberwiseConstructorTest, Availability) {
  EXPECT_AVAILABLE("^struct ^S ^{ int x, y; };");
  // Verify no crashes on incomplete member fields.
  EXPECT_UNAVAILABLE("/*error-ok*/class Forward; class ^A { Forward f;}");
  EXPECT_UNAVAILABLE("struct S { ^int ^x, y; }; struct ^S;");
  EXPECT_UNAVAILABLE("struct ^S {};");
  EXPECT_UNAVAILABLE("union ^S { int x; };");
  EXPECT_UNAVAILABLE("struct ^S { int x = 0; };");
  EXPECT_UNAVAILABLE("struct ^S { struct { int x; }; };");
  EXPECT_UNAVAILABLE("struct ^{ int x; } e;");
}

TEST_F(MemberwiseConstructorTest, Edits) {
  Header = R"cpp(
    struct Move {
      Move(Move&&) = default;
      Move(const Move&) = delete;
    };
    struct Copy {
      Copy(Copy&&) = delete;
      Copy(const Copy&);
    };
  )cpp";
  EXPECT_EQ(apply("struct ^S{Move M; Copy C; int I; int J=4;};"),
            "struct S{"
            "S(Move M, const Copy &C, int I) : M(std::move(M)), C(C), I(I) {}\n"
            "Move M; Copy C; int I; int J=4;};");
}

TEST_F(MemberwiseConstructorTest, FieldTreatment) {
  Header = R"cpp(
    struct MoveOnly {
      MoveOnly(MoveOnly&&) = default;
      MoveOnly(const MoveOnly&) = delete;
    };
    struct CopyOnly {
      CopyOnly(CopyOnly&&) = delete;
      CopyOnly(const CopyOnly&);
    };
    struct CopyTrivial {
      CopyTrivial(CopyTrivial&&) = default;
      CopyTrivial(const CopyTrivial&) = default;
    };
    struct Immovable {
      Immovable(Immovable&&) = delete;
      Immovable(const Immovable&) = delete;
    };
    template <typename T>
    struct Traits { using Type = typename T::Type; };
    using IntAlias = int;
  )cpp";

  auto Fail = Eq("unavailable");
  auto Move = HasSubstr(": Member(std::move(Member))");
  auto CopyRef = AllOf(HasSubstr("S(const "), HasSubstr(": Member(Member)"));
  auto Copy = AllOf(Not(HasSubstr("S(const ")), HasSubstr(": Member(Member)"));
  auto With = [](llvm::StringRef Type) {
    return ("struct ^S { " + Type + " Member; };").str();
  };

  EXPECT_THAT(apply(With("Immovable")), Fail);
  EXPECT_THAT(apply(With("MoveOnly")), Move);
  EXPECT_THAT(apply(With("CopyOnly")), CopyRef);
  EXPECT_THAT(apply(With("CopyTrivial")), Copy);
  EXPECT_THAT(apply(With("int")), Copy);
  EXPECT_THAT(apply(With("IntAlias")), Copy);
  EXPECT_THAT(apply(With("Immovable*")), Copy);
  EXPECT_THAT(apply(With("Immovable&")), Copy);

  EXPECT_THAT(apply("template <typename T>" + With("T")), Move);
  EXPECT_THAT(apply("template <typename T>" + With("typename Traits<T>::Type")),
              Move);
  EXPECT_THAT(apply("template <typename T>" + With("T*")), Copy);
}

} // namespace
} // namespace clangd
} // namespace clang