clang-tools 10.0.0

ExpectedTypeTest.cpp
Go to the documentation of this file.
1 //===-- ExpectedTypeTest.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-exception
6 //
7 //===----------------------------------------------------------------------===//
8
9 #include "ExpectedTypes.h"
10 #include "ParsedAST.h"
11 #include "TestTU.h"
12 #include "clang/AST/ASTContext.h"
13 #include "clang/AST/Decl.h"
14 #include "llvm/ADT/None.h"
15 #include "llvm/ADT/StringRef.h"
16 #include "gmock/gmock.h"
17 #include "gtest/gtest.h"
18
19 namespace clang {
20 namespace clangd {
21 namespace {
22
23 using ::testing::Field;
24 using ::testing::Matcher;
25 using ::testing::SizeIs;
26 using ::testing::UnorderedElementsAreArray;
27
28 class ExpectedTypeConversionTest : public ::testing::Test {
29 protected:
30 void build(llvm::StringRef Code) {
31 assert(!AST && "AST built twice");
32 AST = TestTU::withCode(Code).build();
33 }
34
35 const NamedDecl *decl(llvm::StringRef Name) { return &findDecl(*AST, Name); }
36
37 QualType typeOf(llvm::StringRef Name) {
38 return cast<ValueDecl>(decl(Name))->getType().getCanonicalType();
39 }
40
41 /// An overload for convenience.
42 llvm::Optional<OpaqueType> fromCompletionResult(const NamedDecl *D) {
43 return OpaqueType::fromCompletionResult(
44 ASTCtx(), CodeCompletionResult(D, CCP_Declaration));
45 }
46
47 /// A set of DeclNames whose type match each other computed by
48 /// OpaqueType::fromCompletionResult.
49 using EquivClass = std::set<std::string>;
50
51 Matcher<std::map<std::string, EquivClass>>
52 ClassesAre(llvm::ArrayRef<EquivClass> Classes) {
53 using MapEntry = std::map<std::string, EquivClass>::value_type;
54
55 std::vector<Matcher<MapEntry>> Elements;
56 Elements.reserve(Classes.size());
57 for (auto &Cls : Classes)
58 Elements.push_back(Field(&MapEntry::second, Cls));
59 return UnorderedElementsAreArray(Elements);
60 }
61
62 // Groups \p Decls into equivalence classes based on the result of
63 // 'OpaqueType::fromCompletionResult'.
64 std::map<std::string, EquivClass>
65 buildEquivClasses(llvm::ArrayRef<llvm::StringRef> DeclNames) {
66 std::map<std::string, EquivClass> Classes;
67 for (llvm::StringRef Name : DeclNames) {
68 auto Type = OpaqueType::fromType(ASTCtx(), typeOf(Name));
69 Classes[Type->raw()].insert(Name);
70 }
71 return Classes;
72 }
73
74 ASTContext &ASTCtx() { return AST->getASTContext(); }
75
76 private:
77 // Set after calling build().
78 llvm::Optional<ParsedAST> AST;
79 };
80
81 TEST_F(ExpectedTypeConversionTest, BasicTypes) {
82 build(R"cpp(
83 // ints.
84 bool b;
85 int i;
86 unsigned int ui;
87 long long ll;
88
89 // floats.
90 float f;
91 double d;
92
93 // pointers
94 int* iptr;
95 bool* bptr;
96
97 // user-defined types.
98 struct X {};
99 X user_type;
100 )cpp");
101
102 EXPECT_THAT(buildEquivClasses({"b", "i", "ui", "ll", "f", "d", "iptr", "bptr",
103 "user_type"}),
104 ClassesAre({{"b"},
105 {"i", "ui", "ll"},
106 {"f", "d"},
107 {"iptr"},
108 {"bptr"},
109 {"user_type"}}));
110 }
111
112 TEST_F(ExpectedTypeConversionTest, ReferencesDontMatter) {
113 build(R"cpp(
114 int noref;
115 int & ref = noref;
116 const int & const_ref = noref;
117 int && rv_ref = 10;
118 )cpp");
119
120 EXPECT_THAT(buildEquivClasses({"noref", "ref", "const_ref", "rv_ref"}),
121 SizeIs(1));
122 }
123
124 TEST_F(ExpectedTypeConversionTest, ArraysDecay) {
125 build(R"cpp(
126 int arr[2];
127 int (&arr_ref)[2] = arr;
128 int *ptr;
129 )cpp");
130
131 EXPECT_THAT(buildEquivClasses({"arr", "arr_ref", "ptr"}), SizeIs(1));
132 }
133
134 TEST_F(ExpectedTypeConversionTest, FunctionReturns) {
135 build(R"cpp(
136 int returns_int();
137 int* returns_ptr();
138
139 int int_;
140 int* int_ptr;
141 )cpp");
142
143 OpaqueType IntTy = *OpaqueType::fromType(ASTCtx(), typeOf("int_"));
144 EXPECT_EQ(fromCompletionResult(decl("returns_int")), IntTy);
145
146 OpaqueType IntPtrTy = *OpaqueType::fromType(ASTCtx(), typeOf("int_ptr"));
147 EXPECT_EQ(fromCompletionResult(decl("returns_ptr")), IntPtrTy);
148 }
149
150 TEST_F(ExpectedTypeConversionTest, Templates) {
151 build(R"cpp(
152 template <class T>
153 int* returns_not_dependent();
154 template <class T>
155 T* returns_dependent();
156
157 template <class T>
158 int* var_not_dependent = nullptr;
159 template <class T>
160 T* var_dependent = nullptr;
161
162 int* int_ptr_;
163 )cpp");
164
165 auto IntPtrTy = *OpaqueType::fromType(ASTCtx(), typeOf("int_ptr_"));
166 EXPECT_EQ(fromCompletionResult(decl("returns_not_dependent")), IntPtrTy);
167 EXPECT_EQ(fromCompletionResult(decl("returns_dependent")), llvm::None);
168
169 EXPECT_EQ(fromCompletionResult(decl("var_not_dependent")), IntPtrTy);
170 EXPECT_EQ(fromCompletionResult(decl("var_dependent")), llvm::None);
171 }
172
173 } // namespace
174 } // namespace clangd
175 } // namespace clang
clang::clangd::TestTU::build
ParsedAST build() const
Definition: TestTU.cpp:22
Code
std::string Code
Definition: FindTargetTests.cpp:67
clang::clangd::OpaqueType::fromType
static llvm::Optional< OpaqueType > fromType(ASTContext &Ctx, QualType Type)
Construct an instance from a clang::QualType.
Definition: ExpectedTypes.cpp:81
clang::clangd::TextDocumentSyncKind::None
Documents should not be synced at all.
TestTU.h
clang::clangd::TEST_F
TEST_F(BackgroundIndexTest, NoCrashOnErrorFile)
Definition: BackgroundIndexTests.cpp:88
clang::clangd::SymbolOrigin::AST
clang::clangd::CompletionItemKind::Field
Name
static constexpr llvm::StringLiteral Name
Definition: UppercaseLiteralSuffixCheck.cpp:27
ExpectedTypes.h
clang::clangd::TestTU::withCode
static TestTU withCode(llvm::StringRef Code)
Definition: TestTU.h:33
clang
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//
Definition: ApplyReplacements.h:27
ParsedAST.h
Type
NodeType Type
Definition: HTMLGenerator.cpp:73
clang::clangd::OpaqueType::fromCompletionResult
static llvm::Optional< OpaqueType > fromCompletionResult(ASTContext &Ctx, const CodeCompletionResult &R)
Create a type from a code completion result.
Definition: ExpectedTypes.cpp:87
clang::clangd::findDecl
const NamedDecl & findDecl(ParsedAST &AST, llvm::StringRef QName)
Definition: TestTU.cpp:118