1 //===-- TestTypeSystemClang.cpp -------------------------------------------===//
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 "Plugins/ExpressionParser/Clang/ClangUtil.h"
10 #include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
11 #include "TestingSupport/SubsystemRAII.h"
12 #include "TestingSupport/Symbol/ClangTestUtils.h"
13 #include "lldb/Core/Declaration.h"
14 #include "lldb/Host/FileSystem.h"
15 #include "lldb/Host/HostInfo.h"
16 #include "clang/AST/DeclCXX.h"
17 #include "clang/AST/DeclObjC.h"
18 #include "clang/AST/ExprCXX.h"
19 #include "gtest/gtest.h"
20
21 using namespace clang;
22 using namespace lldb;
23 using namespace lldb_private;
24
25 class TestTypeSystemClang : public testing::Test {
26 public:
27 SubsystemRAII<FileSystem, HostInfo> subsystems;
28
SetUp()29 void SetUp() override {
30 m_ast.reset(
31 new TypeSystemClang("test ASTContext", HostInfo::GetTargetTriple()));
32 }
33
TearDown()34 void TearDown() override { m_ast.reset(); }
35
36 protected:
37 std::unique_ptr<TypeSystemClang> m_ast;
38
GetBasicQualType(BasicType type) const39 QualType GetBasicQualType(BasicType type) const {
40 return ClangUtil::GetQualType(m_ast->GetBasicTypeFromAST(type));
41 }
42
GetBasicQualType(const char * name) const43 QualType GetBasicQualType(const char *name) const {
44 return ClangUtil::GetQualType(
45 m_ast->GetBuiltinTypeByName(ConstString(name)));
46 }
47 };
48
TEST_F(TestTypeSystemClang,TestGetBasicTypeFromEnum)49 TEST_F(TestTypeSystemClang, TestGetBasicTypeFromEnum) {
50 clang::ASTContext &context = m_ast->getASTContext();
51
52 EXPECT_TRUE(
53 context.hasSameType(GetBasicQualType(eBasicTypeBool), context.BoolTy));
54 EXPECT_TRUE(
55 context.hasSameType(GetBasicQualType(eBasicTypeChar), context.CharTy));
56 EXPECT_TRUE(context.hasSameType(GetBasicQualType(eBasicTypeChar8),
57 context.Char8Ty));
58 EXPECT_TRUE(context.hasSameType(GetBasicQualType(eBasicTypeChar16),
59 context.Char16Ty));
60 EXPECT_TRUE(context.hasSameType(GetBasicQualType(eBasicTypeChar32),
61 context.Char32Ty));
62 EXPECT_TRUE(context.hasSameType(GetBasicQualType(eBasicTypeDouble),
63 context.DoubleTy));
64 EXPECT_TRUE(context.hasSameType(GetBasicQualType(eBasicTypeDoubleComplex),
65 context.getComplexType(context.DoubleTy)));
66 EXPECT_TRUE(
67 context.hasSameType(GetBasicQualType(eBasicTypeFloat), context.FloatTy));
68 EXPECT_TRUE(context.hasSameType(GetBasicQualType(eBasicTypeFloatComplex),
69 context.getComplexType(context.FloatTy)));
70 EXPECT_TRUE(
71 context.hasSameType(GetBasicQualType(eBasicTypeHalf), context.HalfTy));
72 EXPECT_TRUE(
73 context.hasSameType(GetBasicQualType(eBasicTypeInt), context.IntTy));
74 EXPECT_TRUE(context.hasSameType(GetBasicQualType(eBasicTypeInt128),
75 context.Int128Ty));
76 EXPECT_TRUE(
77 context.hasSameType(GetBasicQualType(eBasicTypeLong), context.LongTy));
78 EXPECT_TRUE(context.hasSameType(GetBasicQualType(eBasicTypeLongDouble),
79 context.LongDoubleTy));
80 EXPECT_TRUE(
81 context.hasSameType(GetBasicQualType(eBasicTypeLongDoubleComplex),
82 context.getComplexType(context.LongDoubleTy)));
83 EXPECT_TRUE(context.hasSameType(GetBasicQualType(eBasicTypeLongLong),
84 context.LongLongTy));
85 EXPECT_TRUE(context.hasSameType(GetBasicQualType(eBasicTypeNullPtr),
86 context.NullPtrTy));
87 EXPECT_TRUE(context.hasSameType(GetBasicQualType(eBasicTypeObjCClass),
88 context.getObjCClassType()));
89 EXPECT_TRUE(context.hasSameType(GetBasicQualType(eBasicTypeObjCID),
90 context.getObjCIdType()));
91 EXPECT_TRUE(context.hasSameType(GetBasicQualType(eBasicTypeObjCSel),
92 context.getObjCSelType()));
93 EXPECT_TRUE(
94 context.hasSameType(GetBasicQualType(eBasicTypeShort), context.ShortTy));
95 EXPECT_TRUE(context.hasSameType(GetBasicQualType(eBasicTypeSignedChar),
96 context.SignedCharTy));
97 EXPECT_TRUE(context.hasSameType(GetBasicQualType(eBasicTypeUnsignedChar),
98 context.UnsignedCharTy));
99 EXPECT_TRUE(context.hasSameType(GetBasicQualType(eBasicTypeUnsignedInt),
100 context.UnsignedIntTy));
101 EXPECT_TRUE(context.hasSameType(GetBasicQualType(eBasicTypeUnsignedInt128),
102 context.UnsignedInt128Ty));
103 EXPECT_TRUE(context.hasSameType(GetBasicQualType(eBasicTypeUnsignedLong),
104 context.UnsignedLongTy));
105 EXPECT_TRUE(context.hasSameType(GetBasicQualType(eBasicTypeUnsignedLongLong),
106 context.UnsignedLongLongTy));
107 EXPECT_TRUE(context.hasSameType(GetBasicQualType(eBasicTypeUnsignedShort),
108 context.UnsignedShortTy));
109 EXPECT_TRUE(
110 context.hasSameType(GetBasicQualType(eBasicTypeVoid), context.VoidTy));
111 EXPECT_TRUE(
112 context.hasSameType(GetBasicQualType(eBasicTypeWChar), context.WCharTy));
113 }
114
TEST_F(TestTypeSystemClang,TestGetBasicTypeFromName)115 TEST_F(TestTypeSystemClang, TestGetBasicTypeFromName) {
116 EXPECT_EQ(GetBasicQualType(eBasicTypeChar), GetBasicQualType("char"));
117 EXPECT_EQ(GetBasicQualType(eBasicTypeSignedChar),
118 GetBasicQualType("signed char"));
119 EXPECT_EQ(GetBasicQualType(eBasicTypeUnsignedChar),
120 GetBasicQualType("unsigned char"));
121 EXPECT_EQ(GetBasicQualType(eBasicTypeWChar), GetBasicQualType("wchar_t"));
122 EXPECT_EQ(GetBasicQualType(eBasicTypeSignedWChar),
123 GetBasicQualType("signed wchar_t"));
124 EXPECT_EQ(GetBasicQualType(eBasicTypeUnsignedWChar),
125 GetBasicQualType("unsigned wchar_t"));
126 EXPECT_EQ(GetBasicQualType(eBasicTypeShort), GetBasicQualType("short"));
127 EXPECT_EQ(GetBasicQualType(eBasicTypeShort), GetBasicQualType("short int"));
128 EXPECT_EQ(GetBasicQualType(eBasicTypeUnsignedShort),
129 GetBasicQualType("unsigned short"));
130 EXPECT_EQ(GetBasicQualType(eBasicTypeUnsignedShort),
131 GetBasicQualType("unsigned short int"));
132 EXPECT_EQ(GetBasicQualType(eBasicTypeInt), GetBasicQualType("int"));
133 EXPECT_EQ(GetBasicQualType(eBasicTypeInt), GetBasicQualType("signed int"));
134 EXPECT_EQ(GetBasicQualType(eBasicTypeUnsignedInt),
135 GetBasicQualType("unsigned int"));
136 EXPECT_EQ(GetBasicQualType(eBasicTypeUnsignedInt),
137 GetBasicQualType("unsigned"));
138 EXPECT_EQ(GetBasicQualType(eBasicTypeLong), GetBasicQualType("long"));
139 EXPECT_EQ(GetBasicQualType(eBasicTypeLong), GetBasicQualType("long int"));
140 EXPECT_EQ(GetBasicQualType(eBasicTypeUnsignedLong),
141 GetBasicQualType("unsigned long"));
142 EXPECT_EQ(GetBasicQualType(eBasicTypeUnsignedLong),
143 GetBasicQualType("unsigned long int"));
144 EXPECT_EQ(GetBasicQualType(eBasicTypeLongLong),
145 GetBasicQualType("long long"));
146 EXPECT_EQ(GetBasicQualType(eBasicTypeLongLong),
147 GetBasicQualType("long long int"));
148 EXPECT_EQ(GetBasicQualType(eBasicTypeUnsignedLongLong),
149 GetBasicQualType("unsigned long long"));
150 EXPECT_EQ(GetBasicQualType(eBasicTypeUnsignedLongLong),
151 GetBasicQualType("unsigned long long int"));
152 EXPECT_EQ(GetBasicQualType(eBasicTypeInt128), GetBasicQualType("__int128_t"));
153 EXPECT_EQ(GetBasicQualType(eBasicTypeUnsignedInt128),
154 GetBasicQualType("__uint128_t"));
155 EXPECT_EQ(GetBasicQualType(eBasicTypeVoid), GetBasicQualType("void"));
156 EXPECT_EQ(GetBasicQualType(eBasicTypeBool), GetBasicQualType("bool"));
157 EXPECT_EQ(GetBasicQualType(eBasicTypeFloat), GetBasicQualType("float"));
158 EXPECT_EQ(GetBasicQualType(eBasicTypeDouble), GetBasicQualType("double"));
159 EXPECT_EQ(GetBasicQualType(eBasicTypeLongDouble),
160 GetBasicQualType("long double"));
161 EXPECT_EQ(GetBasicQualType(eBasicTypeObjCID), GetBasicQualType("id"));
162 EXPECT_EQ(GetBasicQualType(eBasicTypeObjCSel), GetBasicQualType("SEL"));
163 EXPECT_EQ(GetBasicQualType(eBasicTypeNullPtr), GetBasicQualType("nullptr"));
164 }
165
VerifyEncodingAndBitSize(TypeSystemClang & clang_context,lldb::Encoding encoding,unsigned int bit_size)166 void VerifyEncodingAndBitSize(TypeSystemClang &clang_context,
167 lldb::Encoding encoding, unsigned int bit_size) {
168 clang::ASTContext &context = clang_context.getASTContext();
169
170 CompilerType type =
171 clang_context.GetBuiltinTypeForEncodingAndBitSize(encoding, bit_size);
172 EXPECT_TRUE(type.IsValid());
173
174 QualType qtype = ClangUtil::GetQualType(type);
175 EXPECT_FALSE(qtype.isNull());
176 if (qtype.isNull())
177 return;
178
179 uint64_t actual_size = context.getTypeSize(qtype);
180 EXPECT_EQ(bit_size, actual_size);
181
182 const clang::Type *type_ptr = qtype.getTypePtr();
183 EXPECT_NE(nullptr, type_ptr);
184 if (!type_ptr)
185 return;
186
187 EXPECT_TRUE(type_ptr->isBuiltinType());
188 switch (encoding) {
189 case eEncodingSint:
190 EXPECT_TRUE(type_ptr->isSignedIntegerType());
191 break;
192 case eEncodingUint:
193 EXPECT_TRUE(type_ptr->isUnsignedIntegerType());
194 break;
195 case eEncodingIEEE754:
196 EXPECT_TRUE(type_ptr->isFloatingType());
197 break;
198 default:
199 FAIL() << "Unexpected encoding";
200 break;
201 }
202 }
203
TEST_F(TestTypeSystemClang,TestBuiltinTypeForEncodingAndBitSize)204 TEST_F(TestTypeSystemClang, TestBuiltinTypeForEncodingAndBitSize) {
205 // Make sure we can get types of every possible size in every possible
206 // encoding.
207 // We can't make any guarantee about which specific type we get, because the
208 // standard
209 // isn't that specific. We only need to make sure the compiler hands us some
210 // type that
211 // is both a builtin type and matches the requested bit size.
212 VerifyEncodingAndBitSize(*m_ast, eEncodingSint, 8);
213 VerifyEncodingAndBitSize(*m_ast, eEncodingSint, 16);
214 VerifyEncodingAndBitSize(*m_ast, eEncodingSint, 32);
215 VerifyEncodingAndBitSize(*m_ast, eEncodingSint, 64);
216 VerifyEncodingAndBitSize(*m_ast, eEncodingSint, 128);
217
218 VerifyEncodingAndBitSize(*m_ast, eEncodingUint, 8);
219 VerifyEncodingAndBitSize(*m_ast, eEncodingUint, 16);
220 VerifyEncodingAndBitSize(*m_ast, eEncodingUint, 32);
221 VerifyEncodingAndBitSize(*m_ast, eEncodingUint, 64);
222 VerifyEncodingAndBitSize(*m_ast, eEncodingUint, 128);
223
224 VerifyEncodingAndBitSize(*m_ast, eEncodingIEEE754, 32);
225 VerifyEncodingAndBitSize(*m_ast, eEncodingIEEE754, 64);
226 }
227
TEST_F(TestTypeSystemClang,TestDisplayName)228 TEST_F(TestTypeSystemClang, TestDisplayName) {
229 TypeSystemClang ast("some name", llvm::Triple());
230 EXPECT_EQ("some name", ast.getDisplayName());
231 }
232
TEST_F(TestTypeSystemClang,TestDisplayNameEmpty)233 TEST_F(TestTypeSystemClang, TestDisplayNameEmpty) {
234 TypeSystemClang ast("", llvm::Triple());
235 EXPECT_EQ("", ast.getDisplayName());
236 }
237
TEST_F(TestTypeSystemClang,TestGetEnumIntegerTypeInvalid)238 TEST_F(TestTypeSystemClang, TestGetEnumIntegerTypeInvalid) {
239 EXPECT_FALSE(m_ast->GetEnumerationIntegerType(CompilerType()).IsValid());
240 }
241
TEST_F(TestTypeSystemClang,TestGetEnumIntegerTypeUnexpectedType)242 TEST_F(TestTypeSystemClang, TestGetEnumIntegerTypeUnexpectedType) {
243 CompilerType int_type = m_ast->GetBasicType(lldb::eBasicTypeInt);
244 CompilerType t = m_ast->GetEnumerationIntegerType(int_type);
245 EXPECT_FALSE(t.IsValid());
246 }
247
TEST_F(TestTypeSystemClang,TestGetEnumIntegerTypeBasicTypes)248 TEST_F(TestTypeSystemClang, TestGetEnumIntegerTypeBasicTypes) {
249 // All possible underlying integer types of enums.
250 const std::vector<lldb::BasicType> types_to_test = {
251 eBasicTypeInt, eBasicTypeUnsignedInt, eBasicTypeLong,
252 eBasicTypeUnsignedLong, eBasicTypeLongLong, eBasicTypeUnsignedLongLong,
253 };
254
255 for (bool scoped : {true, false}) {
256 SCOPED_TRACE("scoped: " + std::to_string(scoped));
257 for (lldb::BasicType basic_type : types_to_test) {
258 SCOPED_TRACE(std::to_string(basic_type));
259
260 TypeSystemClang ast("enum_ast", HostInfo::GetTargetTriple());
261 CompilerType basic_compiler_type = ast.GetBasicType(basic_type);
262 EXPECT_TRUE(basic_compiler_type.IsValid());
263
264 CompilerType enum_type = ast.CreateEnumerationType(
265 "my_enum", ast.GetTranslationUnitDecl(), OptionalClangModuleID(),
266 Declaration(), basic_compiler_type, scoped);
267
268 CompilerType t = ast.GetEnumerationIntegerType(enum_type);
269 // Check that the type we put in at the start is found again.
270 EXPECT_EQ(basic_compiler_type.GetTypeName(), t.GetTypeName());
271 }
272 }
273 }
274
TEST_F(TestTypeSystemClang,TestOwningModule)275 TEST_F(TestTypeSystemClang, TestOwningModule) {
276 TypeSystemClang ast("module_ast", HostInfo::GetTargetTriple());
277 CompilerType basic_compiler_type = ast.GetBasicType(BasicType::eBasicTypeInt);
278 CompilerType enum_type = ast.CreateEnumerationType(
279 "my_enum", ast.GetTranslationUnitDecl(), OptionalClangModuleID(100),
280 Declaration(), basic_compiler_type, false);
281 auto *ed = TypeSystemClang::GetAsEnumDecl(enum_type);
282 EXPECT_FALSE(!ed);
283 EXPECT_EQ(ed->getOwningModuleID(), 100u);
284
285 CompilerType record_type = ast.CreateRecordType(
286 nullptr, OptionalClangModuleID(200), lldb::eAccessPublic, "FooRecord",
287 clang::TTK_Struct, lldb::eLanguageTypeC_plus_plus, nullptr);
288 auto *rd = TypeSystemClang::GetAsRecordDecl(record_type);
289 EXPECT_FALSE(!rd);
290 EXPECT_EQ(rd->getOwningModuleID(), 200u);
291
292 CompilerType class_type =
293 ast.CreateObjCClass("objc_class", ast.GetTranslationUnitDecl(),
294 OptionalClangModuleID(300), false, false);
295 auto *cd = TypeSystemClang::GetAsObjCInterfaceDecl(class_type);
296 EXPECT_FALSE(!cd);
297 EXPECT_EQ(cd->getOwningModuleID(), 300u);
298 }
299
TEST_F(TestTypeSystemClang,TestIsClangType)300 TEST_F(TestTypeSystemClang, TestIsClangType) {
301 clang::ASTContext &context = m_ast->getASTContext();
302 lldb::opaque_compiler_type_t bool_ctype =
303 TypeSystemClang::GetOpaqueCompilerType(&context, lldb::eBasicTypeBool);
304 CompilerType bool_type(m_ast.get(), bool_ctype);
305 CompilerType record_type = m_ast->CreateRecordType(
306 nullptr, OptionalClangModuleID(100), lldb::eAccessPublic, "FooRecord",
307 clang::TTK_Struct, lldb::eLanguageTypeC_plus_plus, nullptr);
308 // Clang builtin type and record type should pass
309 EXPECT_TRUE(ClangUtil::IsClangType(bool_type));
310 EXPECT_TRUE(ClangUtil::IsClangType(record_type));
311
312 // Default constructed type should fail
313 EXPECT_FALSE(ClangUtil::IsClangType(CompilerType()));
314 }
315
TEST_F(TestTypeSystemClang,TestRemoveFastQualifiers)316 TEST_F(TestTypeSystemClang, TestRemoveFastQualifiers) {
317 CompilerType record_type = m_ast->CreateRecordType(
318 nullptr, OptionalClangModuleID(), lldb::eAccessPublic, "FooRecord",
319 clang::TTK_Struct, lldb::eLanguageTypeC_plus_plus, nullptr);
320 QualType qt;
321
322 qt = ClangUtil::GetQualType(record_type);
323 EXPECT_EQ(0u, qt.getLocalFastQualifiers());
324 record_type = record_type.AddConstModifier();
325 record_type = record_type.AddVolatileModifier();
326 record_type = record_type.AddRestrictModifier();
327 qt = ClangUtil::GetQualType(record_type);
328 EXPECT_NE(0u, qt.getLocalFastQualifiers());
329 record_type = ClangUtil::RemoveFastQualifiers(record_type);
330 qt = ClangUtil::GetQualType(record_type);
331 EXPECT_EQ(0u, qt.getLocalFastQualifiers());
332 }
333
TEST_F(TestTypeSystemClang,TestConvertAccessTypeToAccessSpecifier)334 TEST_F(TestTypeSystemClang, TestConvertAccessTypeToAccessSpecifier) {
335 EXPECT_EQ(AS_none,
336 TypeSystemClang::ConvertAccessTypeToAccessSpecifier(eAccessNone));
337 EXPECT_EQ(AS_none, TypeSystemClang::ConvertAccessTypeToAccessSpecifier(
338 eAccessPackage));
339 EXPECT_EQ(AS_public,
340 TypeSystemClang::ConvertAccessTypeToAccessSpecifier(eAccessPublic));
341 EXPECT_EQ(AS_private, TypeSystemClang::ConvertAccessTypeToAccessSpecifier(
342 eAccessPrivate));
343 EXPECT_EQ(AS_protected, TypeSystemClang::ConvertAccessTypeToAccessSpecifier(
344 eAccessProtected));
345 }
346
TEST_F(TestTypeSystemClang,TestUnifyAccessSpecifiers)347 TEST_F(TestTypeSystemClang, TestUnifyAccessSpecifiers) {
348 // Unifying two of the same type should return the same type
349 EXPECT_EQ(AS_public,
350 TypeSystemClang::UnifyAccessSpecifiers(AS_public, AS_public));
351 EXPECT_EQ(AS_private,
352 TypeSystemClang::UnifyAccessSpecifiers(AS_private, AS_private));
353 EXPECT_EQ(AS_protected,
354 TypeSystemClang::UnifyAccessSpecifiers(AS_protected, AS_protected));
355
356 // Otherwise the result should be the strictest of the two.
357 EXPECT_EQ(AS_private,
358 TypeSystemClang::UnifyAccessSpecifiers(AS_private, AS_public));
359 EXPECT_EQ(AS_private,
360 TypeSystemClang::UnifyAccessSpecifiers(AS_private, AS_protected));
361 EXPECT_EQ(AS_private,
362 TypeSystemClang::UnifyAccessSpecifiers(AS_public, AS_private));
363 EXPECT_EQ(AS_private,
364 TypeSystemClang::UnifyAccessSpecifiers(AS_protected, AS_private));
365 EXPECT_EQ(AS_protected,
366 TypeSystemClang::UnifyAccessSpecifiers(AS_protected, AS_public));
367 EXPECT_EQ(AS_protected,
368 TypeSystemClang::UnifyAccessSpecifiers(AS_public, AS_protected));
369
370 // None is stricter than everything (by convention)
371 EXPECT_EQ(AS_none,
372 TypeSystemClang::UnifyAccessSpecifiers(AS_none, AS_public));
373 EXPECT_EQ(AS_none,
374 TypeSystemClang::UnifyAccessSpecifiers(AS_none, AS_protected));
375 EXPECT_EQ(AS_none,
376 TypeSystemClang::UnifyAccessSpecifiers(AS_none, AS_private));
377 EXPECT_EQ(AS_none,
378 TypeSystemClang::UnifyAccessSpecifiers(AS_public, AS_none));
379 EXPECT_EQ(AS_none,
380 TypeSystemClang::UnifyAccessSpecifiers(AS_protected, AS_none));
381 EXPECT_EQ(AS_none,
382 TypeSystemClang::UnifyAccessSpecifiers(AS_private, AS_none));
383 }
384
TEST_F(TestTypeSystemClang,TestRecordHasFields)385 TEST_F(TestTypeSystemClang, TestRecordHasFields) {
386 CompilerType int_type = m_ast->GetBasicType(eBasicTypeInt);
387
388 // Test that a record with no fields returns false
389 CompilerType empty_base = m_ast->CreateRecordType(
390 nullptr, OptionalClangModuleID(), lldb::eAccessPublic, "EmptyBase",
391 clang::TTK_Struct, lldb::eLanguageTypeC_plus_plus, nullptr);
392 TypeSystemClang::StartTagDeclarationDefinition(empty_base);
393 TypeSystemClang::CompleteTagDeclarationDefinition(empty_base);
394
395 RecordDecl *empty_base_decl = TypeSystemClang::GetAsRecordDecl(empty_base);
396 EXPECT_NE(nullptr, empty_base_decl);
397 EXPECT_FALSE(TypeSystemClang::RecordHasFields(empty_base_decl));
398
399 // Test that a record with direct fields returns true
400 CompilerType non_empty_base = m_ast->CreateRecordType(
401 nullptr, OptionalClangModuleID(), lldb::eAccessPublic, "NonEmptyBase",
402 clang::TTK_Struct, lldb::eLanguageTypeC_plus_plus, nullptr);
403 TypeSystemClang::StartTagDeclarationDefinition(non_empty_base);
404 FieldDecl *non_empty_base_field_decl = m_ast->AddFieldToRecordType(
405 non_empty_base, "MyField", int_type, eAccessPublic, 0);
406 TypeSystemClang::CompleteTagDeclarationDefinition(non_empty_base);
407 RecordDecl *non_empty_base_decl =
408 TypeSystemClang::GetAsRecordDecl(non_empty_base);
409 EXPECT_NE(nullptr, non_empty_base_decl);
410 EXPECT_NE(nullptr, non_empty_base_field_decl);
411 EXPECT_TRUE(TypeSystemClang::RecordHasFields(non_empty_base_decl));
412
413 std::vector<std::unique_ptr<clang::CXXBaseSpecifier>> bases;
414
415 // Test that a record with no direct fields, but fields in a base returns true
416 CompilerType empty_derived = m_ast->CreateRecordType(
417 nullptr, OptionalClangModuleID(), lldb::eAccessPublic, "EmptyDerived",
418 clang::TTK_Struct, lldb::eLanguageTypeC_plus_plus, nullptr);
419 TypeSystemClang::StartTagDeclarationDefinition(empty_derived);
420 std::unique_ptr<clang::CXXBaseSpecifier> non_empty_base_spec =
421 m_ast->CreateBaseClassSpecifier(non_empty_base.GetOpaqueQualType(),
422 lldb::eAccessPublic, false, false);
423 bases.push_back(std::move(non_empty_base_spec));
424 bool result = m_ast->TransferBaseClasses(empty_derived.GetOpaqueQualType(),
425 std::move(bases));
426 TypeSystemClang::CompleteTagDeclarationDefinition(empty_derived);
427 EXPECT_TRUE(result);
428 CXXRecordDecl *empty_derived_non_empty_base_cxx_decl =
429 m_ast->GetAsCXXRecordDecl(empty_derived.GetOpaqueQualType());
430 RecordDecl *empty_derived_non_empty_base_decl =
431 TypeSystemClang::GetAsRecordDecl(empty_derived);
432 EXPECT_EQ(1u, TypeSystemClang::GetNumBaseClasses(
433 empty_derived_non_empty_base_cxx_decl, false));
434 EXPECT_TRUE(
435 TypeSystemClang::RecordHasFields(empty_derived_non_empty_base_decl));
436
437 // Test that a record with no direct fields, but fields in a virtual base
438 // returns true
439 CompilerType empty_derived2 = m_ast->CreateRecordType(
440 nullptr, OptionalClangModuleID(), lldb::eAccessPublic, "EmptyDerived2",
441 clang::TTK_Struct, lldb::eLanguageTypeC_plus_plus, nullptr);
442 TypeSystemClang::StartTagDeclarationDefinition(empty_derived2);
443 std::unique_ptr<CXXBaseSpecifier> non_empty_vbase_spec =
444 m_ast->CreateBaseClassSpecifier(non_empty_base.GetOpaqueQualType(),
445 lldb::eAccessPublic, true, false);
446 bases.push_back(std::move(non_empty_vbase_spec));
447 result = m_ast->TransferBaseClasses(empty_derived2.GetOpaqueQualType(),
448 std::move(bases));
449 TypeSystemClang::CompleteTagDeclarationDefinition(empty_derived2);
450 EXPECT_TRUE(result);
451 CXXRecordDecl *empty_derived_non_empty_vbase_cxx_decl =
452 m_ast->GetAsCXXRecordDecl(empty_derived2.GetOpaqueQualType());
453 RecordDecl *empty_derived_non_empty_vbase_decl =
454 TypeSystemClang::GetAsRecordDecl(empty_derived2);
455 EXPECT_EQ(1u, TypeSystemClang::GetNumBaseClasses(
456 empty_derived_non_empty_vbase_cxx_decl, false));
457 EXPECT_TRUE(
458 TypeSystemClang::RecordHasFields(empty_derived_non_empty_vbase_decl));
459 }
460
TEST_F(TestTypeSystemClang,TemplateArguments)461 TEST_F(TestTypeSystemClang, TemplateArguments) {
462 TypeSystemClang::TemplateParameterInfos infos;
463 infos.names.push_back("T");
464 infos.args.push_back(TemplateArgument(m_ast->getASTContext().IntTy));
465 infos.names.push_back("I");
466 llvm::APSInt arg(llvm::APInt(8, 47));
467 infos.args.push_back(TemplateArgument(m_ast->getASTContext(), arg,
468 m_ast->getASTContext().IntTy));
469
470 // template<typename T, int I> struct foo;
471 ClassTemplateDecl *decl = m_ast->CreateClassTemplateDecl(
472 m_ast->GetTranslationUnitDecl(), OptionalClangModuleID(), eAccessPublic,
473 "foo", TTK_Struct, infos);
474 ASSERT_NE(decl, nullptr);
475
476 // foo<int, 47>
477 ClassTemplateSpecializationDecl *spec_decl =
478 m_ast->CreateClassTemplateSpecializationDecl(
479 m_ast->GetTranslationUnitDecl(), OptionalClangModuleID(), decl,
480 TTK_Struct, infos);
481 ASSERT_NE(spec_decl, nullptr);
482 CompilerType type = m_ast->CreateClassTemplateSpecializationType(spec_decl);
483 ASSERT_TRUE(type);
484 m_ast->StartTagDeclarationDefinition(type);
485 m_ast->CompleteTagDeclarationDefinition(type);
486
487 // typedef foo<int, 47> foo_def;
488 CompilerType typedef_type = type.CreateTypedef(
489 "foo_def", m_ast->CreateDeclContext(m_ast->GetTranslationUnitDecl()), 0);
490
491 CompilerType auto_type(
492 m_ast.get(),
493 m_ast->getASTContext()
494 .getAutoType(ClangUtil::GetCanonicalQualType(typedef_type),
495 clang::AutoTypeKeyword::Auto, false)
496 .getAsOpaquePtr());
497
498 CompilerType int_type(m_ast.get(),
499 m_ast->getASTContext().IntTy.getAsOpaquePtr());
500 for (CompilerType t : {type, typedef_type, auto_type}) {
501 SCOPED_TRACE(t.GetTypeName().AsCString());
502
503 const bool expand_pack = false;
504 EXPECT_EQ(
505 m_ast->GetTemplateArgumentKind(t.GetOpaqueQualType(), 0, expand_pack),
506 eTemplateArgumentKindType);
507 EXPECT_EQ(
508 m_ast->GetTypeTemplateArgument(t.GetOpaqueQualType(), 0, expand_pack),
509 int_type);
510 EXPECT_EQ(llvm::None, m_ast->GetIntegralTemplateArgument(
511 t.GetOpaqueQualType(), 0, expand_pack));
512
513 EXPECT_EQ(
514 m_ast->GetTemplateArgumentKind(t.GetOpaqueQualType(), 1, expand_pack),
515 eTemplateArgumentKindIntegral);
516 EXPECT_EQ(
517 m_ast->GetTypeTemplateArgument(t.GetOpaqueQualType(), 1, expand_pack),
518 CompilerType());
519 auto result = m_ast->GetIntegralTemplateArgument(t.GetOpaqueQualType(), 1,
520 expand_pack);
521 ASSERT_NE(llvm::None, result);
522 EXPECT_EQ(arg, result->value);
523 EXPECT_EQ(int_type, result->type);
524 }
525 }
526
527 class TestCreateClassTemplateDecl : public TestTypeSystemClang {
528 protected:
529 /// The class templates created so far by the Expect* functions below.
530 llvm::DenseSet<ClassTemplateDecl *> m_created_templates;
531
532 /// Utility function for creating a class template.
533 ClassTemplateDecl *
CreateClassTemplate(const TypeSystemClang::TemplateParameterInfos & infos)534 CreateClassTemplate(const TypeSystemClang::TemplateParameterInfos &infos) {
535 ClassTemplateDecl *decl = m_ast->CreateClassTemplateDecl(
536 m_ast->GetTranslationUnitDecl(), OptionalClangModuleID(), eAccessPublic,
537 "foo", TTK_Struct, infos);
538 return decl;
539 }
540
541 /// Creates a new class template with the given template parameters.
542 /// Asserts that a new ClassTemplateDecl is created.
543 /// \param description The gtest scope string that should describe the input.
544 /// \param infos The template parameters that the class template should have.
545 /// \returns The created ClassTemplateDecl.
546 ClassTemplateDecl *
ExpectNewTemplate(std::string description,const TypeSystemClang::TemplateParameterInfos & infos)547 ExpectNewTemplate(std::string description,
548 const TypeSystemClang::TemplateParameterInfos &infos) {
549 SCOPED_TRACE(description);
550 ClassTemplateDecl *first_template = CreateClassTemplate(infos);
551 // A new template should have been created.
552 EXPECT_FALSE(m_created_templates.contains(first_template))
553 << "Didn't create new class template but reused this existing decl:\n"
554 << ClangUtil::DumpDecl(first_template);
555 m_created_templates.insert(first_template);
556
557 // Creating a new template with the same arguments should always return
558 // the template created above.
559 ClassTemplateDecl *second_template = CreateClassTemplate(infos);
560 EXPECT_EQ(first_template, second_template)
561 << "Second attempt to create class template didn't reuse first decl:\n"
562 << ClangUtil::DumpDecl(first_template) << "\nInstead created/reused:\n"
563 << ClangUtil::DumpDecl(second_template);
564 return first_template;
565 }
566
567 /// Tries to create a new class template but asserts that an existing class
568 /// template in the current AST is reused (in contract so a new class
569 /// template being created).
570 /// \param description The gtest scope string that should describe the input.
571 /// \param infos The template parameters that the class template should have.
572 void
ExpectReusedTemplate(std::string description,const TypeSystemClang::TemplateParameterInfos & infos,ClassTemplateDecl * expected)573 ExpectReusedTemplate(std::string description,
574 const TypeSystemClang::TemplateParameterInfos &infos,
575 ClassTemplateDecl *expected) {
576 SCOPED_TRACE(description);
577 ClassTemplateDecl *td = CreateClassTemplate(infos);
578 EXPECT_EQ(td, expected)
579 << "Created/reused class template is:\n"
580 << ClangUtil::DumpDecl(td) << "\nExpected to reuse:\n"
581 << ClangUtil::DumpDecl(expected);
582 }
583 };
584
TEST_F(TestCreateClassTemplateDecl,FindExistingTemplates)585 TEST_F(TestCreateClassTemplateDecl, FindExistingTemplates) {
586 // This tests the logic in TypeSystemClang::CreateClassTemplateDecl that
587 // decides whether an existing ClassTemplateDecl in the AST can be reused.
588 // The behaviour should follow the C++ rules for redeclaring templates
589 // (e.g., parameter names can be changed/omitted.)
590
591 // This describes a class template *instantiation* from which we will infer
592 // the structure of the class template.
593 TypeSystemClang::TemplateParameterInfos infos;
594
595 // Test an empty template parameter list: <>
596 ExpectNewTemplate("<>", infos);
597
598 // Test that <typename T> with T = int creates a new template.
599 infos.names = {"T"};
600 infos.args = {TemplateArgument(m_ast->getASTContext().IntTy)};
601 ClassTemplateDecl *single_type_arg = ExpectNewTemplate("<typename T>", infos);
602
603 // Test that changing the parameter name doesn't create a new class template.
604 infos.names = {"A"};
605 ExpectReusedTemplate("<typename A> (A = int)", infos, single_type_arg);
606
607 // Test that changing the used type doesn't create a new class template.
608 infos.args = {TemplateArgument(m_ast->getASTContext().FloatTy)};
609 ExpectReusedTemplate("<typename A> (A = float)", infos, single_type_arg);
610
611 // Test that <typename A, signed char I> creates a new template with A = int
612 // and I = 47;
613 infos.names.push_back("I");
614 infos.args.push_back(TemplateArgument(m_ast->getASTContext(),
615 llvm::APSInt(llvm::APInt(8, 47)),
616 m_ast->getASTContext().SignedCharTy));
617 ClassTemplateDecl *type_and_char_value =
618 ExpectNewTemplate("<typename A, signed char I> (I = 47)", infos);
619
620 // Change the value of the I parameter to 123. The previously created
621 // class template should still be reused.
622 infos.args.pop_back();
623 infos.args.push_back(TemplateArgument(m_ast->getASTContext(),
624 llvm::APSInt(llvm::APInt(8, 123)),
625 m_ast->getASTContext().SignedCharTy));
626 ExpectReusedTemplate("<typename A, signed char I> (I = 123)", infos,
627 type_and_char_value);
628
629 // Change the type of the I parameter to int so we have <typename A, int I>.
630 // The class template from above can't be reused.
631 infos.args.pop_back();
632 infos.args.push_back(TemplateArgument(m_ast->getASTContext(),
633 llvm::APSInt(llvm::APInt(32, 47)),
634 m_ast->getASTContext().IntTy));
635 ExpectNewTemplate("<typename A, int I> (I = 123)", infos);
636
637 // Test a second type parameter will also cause a new template to be created.
638 // We now have <typename A, int I, typename B>.
639 infos.names.push_back("B");
640 infos.args.push_back(TemplateArgument(m_ast->getASTContext().IntTy));
641 ClassTemplateDecl *type_and_char_value_and_type =
642 ExpectNewTemplate("<typename A, int I, typename B>", infos);
643
644 // Remove all the names from the parameters which shouldn't influence the
645 // way the templates get merged.
646 infos.names = {"", "", ""};
647 ExpectReusedTemplate("<typename, int, typename>", infos,
648 type_and_char_value_and_type);
649 }
650
TEST_F(TestCreateClassTemplateDecl,FindExistingTemplatesWithParameterPack)651 TEST_F(TestCreateClassTemplateDecl, FindExistingTemplatesWithParameterPack) {
652 // The same as FindExistingTemplates but for templates with parameter packs.
653
654 TypeSystemClang::TemplateParameterInfos infos;
655 infos.packed_args =
656 std::make_unique<TypeSystemClang::TemplateParameterInfos>();
657 infos.packed_args->names = {"", ""};
658 infos.packed_args->args = {TemplateArgument(m_ast->getASTContext().IntTy),
659 TemplateArgument(m_ast->getASTContext().IntTy)};
660 ClassTemplateDecl *type_pack =
661 ExpectNewTemplate("<typename ...> (int, int)", infos);
662
663 // Special case: An instantiation for a parameter pack with no values fits
664 // to whatever class template we find. There isn't enough information to
665 // do an actual comparison here.
666 infos.packed_args =
667 std::make_unique<TypeSystemClang::TemplateParameterInfos>();
668 ExpectReusedTemplate("<...> (no values in pack)", infos, type_pack);
669
670 // Change the type content of pack type values.
671 infos.packed_args->names = {"", ""};
672 infos.packed_args->args = {TemplateArgument(m_ast->getASTContext().IntTy),
673 TemplateArgument(m_ast->getASTContext().LongTy)};
674 ExpectReusedTemplate("<typename ...> (int, long)", infos, type_pack);
675
676 // Change the number of pack values.
677 infos.packed_args->args = {TemplateArgument(m_ast->getASTContext().IntTy)};
678 ExpectReusedTemplate("<typename ...> (int)", infos, type_pack);
679
680 // The names of the pack values shouldn't matter.
681 infos.packed_args->names = {"A", "B"};
682 ExpectReusedTemplate("<typename ...> (int)", infos, type_pack);
683
684 // Changing the kind of template argument will create a new template.
685 infos.packed_args->args = {TemplateArgument(m_ast->getASTContext(),
686 llvm::APSInt(llvm::APInt(32, 1)),
687 m_ast->getASTContext().IntTy)};
688 ClassTemplateDecl *int_pack = ExpectNewTemplate("<int ...> (int = 1)", infos);
689
690 // Changing the value of integral parameters will not create a new template.
691 infos.packed_args->args = {TemplateArgument(
692 m_ast->getASTContext(), llvm::APSInt(llvm::APInt(32, 123)),
693 m_ast->getASTContext().IntTy)};
694 ExpectReusedTemplate("<int ...> (int = 123)", infos, int_pack);
695
696 // Changing the integral type will create a new template.
697 infos.packed_args->args = {TemplateArgument(m_ast->getASTContext(),
698 llvm::APSInt(llvm::APInt(64, 1)),
699 m_ast->getASTContext().LongTy)};
700 ExpectNewTemplate("<long ...> (long = 1)", infos);
701
702 // Prependinding a non-pack parameter will create a new template.
703 infos.names = {"T"};
704 infos.args = {TemplateArgument(m_ast->getASTContext().IntTy)};
705 ExpectNewTemplate("<typename T, long...> (T = int, long = 1)", infos);
706 }
707
TEST_F(TestTypeSystemClang,OnlyPackName)708 TEST_F(TestTypeSystemClang, OnlyPackName) {
709 TypeSystemClang::TemplateParameterInfos infos;
710 infos.pack_name = "A";
711 EXPECT_FALSE(infos.IsValid());
712 }
713
makeConstInt(clang::ASTContext & ctxt)714 static QualType makeConstInt(clang::ASTContext &ctxt) {
715 QualType result(ctxt.IntTy);
716 result.addConst();
717 return result;
718 }
719
TEST_F(TestTypeSystemClang,TestGetTypeClassDeclType)720 TEST_F(TestTypeSystemClang, TestGetTypeClassDeclType) {
721 clang::ASTContext &ctxt = m_ast->getASTContext();
722 auto *nullptr_expr = new (ctxt) CXXNullPtrLiteralExpr(ctxt.NullPtrTy, SourceLocation());
723 QualType t = ctxt.getDecltypeType(nullptr_expr, makeConstInt(ctxt));
724 EXPECT_EQ(lldb::eTypeClassBuiltin, m_ast->GetTypeClass(t.getAsOpaquePtr()));
725 }
726
TEST_F(TestTypeSystemClang,TestGetTypeClassTypeOf)727 TEST_F(TestTypeSystemClang, TestGetTypeClassTypeOf) {
728 clang::ASTContext &ctxt = m_ast->getASTContext();
729 QualType t = ctxt.getTypeOfType(makeConstInt(ctxt));
730 EXPECT_EQ(lldb::eTypeClassBuiltin, m_ast->GetTypeClass(t.getAsOpaquePtr()));
731 }
732
TEST_F(TestTypeSystemClang,TestGetTypeClassTypeOfExpr)733 TEST_F(TestTypeSystemClang, TestGetTypeClassTypeOfExpr) {
734 clang::ASTContext &ctxt = m_ast->getASTContext();
735 auto *nullptr_expr = new (ctxt) CXXNullPtrLiteralExpr(ctxt.NullPtrTy, SourceLocation());
736 QualType t = ctxt.getTypeOfExprType(nullptr_expr);
737 EXPECT_EQ(lldb::eTypeClassBuiltin, m_ast->GetTypeClass(t.getAsOpaquePtr()));
738 }
739
TEST_F(TestTypeSystemClang,TestGetTypeClassNested)740 TEST_F(TestTypeSystemClang, TestGetTypeClassNested) {
741 clang::ASTContext &ctxt = m_ast->getASTContext();
742 QualType t_base = ctxt.getTypeOfType(makeConstInt(ctxt));
743 QualType t = ctxt.getTypeOfType(t_base);
744 EXPECT_EQ(lldb::eTypeClassBuiltin, m_ast->GetTypeClass(t.getAsOpaquePtr()));
745 }
746
TEST_F(TestTypeSystemClang,TestFunctionTemplateConstruction)747 TEST_F(TestTypeSystemClang, TestFunctionTemplateConstruction) {
748 // Tests creating a function template.
749
750 CompilerType int_type = m_ast->GetBasicType(lldb::eBasicTypeInt);
751 clang::TranslationUnitDecl *TU = m_ast->GetTranslationUnitDecl();
752
753 // Prepare the declarations/types we need for the template.
754 CompilerType clang_type =
755 m_ast->CreateFunctionType(int_type, nullptr, 0U, false, 0U);
756 FunctionDecl *func = m_ast->CreateFunctionDeclaration(
757 TU, OptionalClangModuleID(), "foo", clang_type, StorageClass::SC_None,
758 false);
759 TypeSystemClang::TemplateParameterInfos empty_params;
760
761 // Create the actual function template.
762 clang::FunctionTemplateDecl *func_template =
763 m_ast->CreateFunctionTemplateDecl(TU, OptionalClangModuleID(), func,
764 empty_params);
765
766 EXPECT_EQ(TU, func_template->getDeclContext());
767 EXPECT_EQ("foo", func_template->getName());
768 EXPECT_EQ(clang::AccessSpecifier::AS_none, func_template->getAccess());
769 }
770
TEST_F(TestTypeSystemClang,TestFunctionTemplateInRecordConstruction)771 TEST_F(TestTypeSystemClang, TestFunctionTemplateInRecordConstruction) {
772 // Tests creating a function template inside a record.
773
774 CompilerType int_type = m_ast->GetBasicType(lldb::eBasicTypeInt);
775 clang::TranslationUnitDecl *TU = m_ast->GetTranslationUnitDecl();
776
777 // Create a record we can put the function template int.
778 CompilerType record_type =
779 clang_utils::createRecordWithField(*m_ast, "record", int_type, "field");
780 clang::TagDecl *record = ClangUtil::GetAsTagDecl(record_type);
781
782 // Prepare the declarations/types we need for the template.
783 CompilerType clang_type =
784 m_ast->CreateFunctionType(int_type, nullptr, 0U, false, 0U);
785 // We create the FunctionDecl for the template in the TU DeclContext because:
786 // 1. FunctionDecls can't be in a Record (only CXXMethodDecls can).
787 // 2. It is mirroring the behavior of DWARFASTParserClang::ParseSubroutine.
788 FunctionDecl *func = m_ast->CreateFunctionDeclaration(
789 TU, OptionalClangModuleID(), "foo", clang_type, StorageClass::SC_None,
790 false);
791 TypeSystemClang::TemplateParameterInfos empty_params;
792
793 // Create the actual function template.
794 clang::FunctionTemplateDecl *func_template =
795 m_ast->CreateFunctionTemplateDecl(record, OptionalClangModuleID(), func,
796 empty_params);
797
798 EXPECT_EQ(record, func_template->getDeclContext());
799 EXPECT_EQ("foo", func_template->getName());
800 EXPECT_EQ(clang::AccessSpecifier::AS_public, func_template->getAccess());
801 }
802
TEST_F(TestTypeSystemClang,TestDeletingImplicitCopyCstrDueToMoveCStr)803 TEST_F(TestTypeSystemClang, TestDeletingImplicitCopyCstrDueToMoveCStr) {
804 // We need to simulate this behavior in our AST that we construct as we don't
805 // have a Sema instance that can do this for us:
806 // C++11 [class.copy]p7, p18:
807 // If the class definition declares a move constructor or move assignment
808 // operator, an implicitly declared copy constructor or copy assignment
809 // operator is defined as deleted.
810
811 // Create a record and start defining it.
812 llvm::StringRef class_name = "S";
813 CompilerType t = clang_utils::createRecord(*m_ast, class_name);
814 m_ast->StartTagDeclarationDefinition(t);
815
816 // Create a move constructor that will delete the implicit copy constructor.
817 CompilerType return_type = m_ast->GetBasicType(lldb::eBasicTypeVoid);
818 CompilerType param_type = t.GetRValueReferenceType();
819 CompilerType function_type =
820 m_ast->CreateFunctionType(return_type, ¶m_type, /*num_params*/ 1,
821 /*variadic=*/false, /*quals*/ 0U);
822 bool is_virtual = false;
823 bool is_static = false;
824 bool is_inline = false;
825 bool is_explicit = true;
826 bool is_attr_used = false;
827 bool is_artificial = false;
828 m_ast->AddMethodToCXXRecordType(
829 t.GetOpaqueQualType(), class_name, nullptr, function_type,
830 lldb::AccessType::eAccessPublic, is_virtual, is_static, is_inline,
831 is_explicit, is_attr_used, is_artificial);
832
833 // Complete the definition and check the created record.
834 m_ast->CompleteTagDeclarationDefinition(t);
835 auto *record = llvm::cast<CXXRecordDecl>(ClangUtil::GetAsTagDecl(t));
836 // We can't call defaultedCopyConstructorIsDeleted() as this requires that
837 // the Decl passes through Sema which will actually compute this field.
838 // Instead we check that there is no copy constructor declared by the user
839 // which only leaves a non-deleted defaulted copy constructor as an option
840 // that our record will have no simple copy constructor.
841 EXPECT_FALSE(record->hasUserDeclaredCopyConstructor());
842 EXPECT_FALSE(record->hasSimpleCopyConstructor());
843 }
844
TEST_F(TestTypeSystemClang,TestNotDeletingUserCopyCstrDueToMoveCStr)845 TEST_F(TestTypeSystemClang, TestNotDeletingUserCopyCstrDueToMoveCStr) {
846 // Tests that we don't delete the a user-defined copy constructor when
847 // a move constructor is provided.
848 // See also the TestDeletingImplicitCopyCstrDueToMoveCStr test.
849 llvm::StringRef class_name = "S";
850 CompilerType t = clang_utils::createRecord(*m_ast, class_name);
851 m_ast->StartTagDeclarationDefinition(t);
852
853 CompilerType return_type = m_ast->GetBasicType(lldb::eBasicTypeVoid);
854 bool is_virtual = false;
855 bool is_static = false;
856 bool is_inline = false;
857 bool is_explicit = true;
858 bool is_attr_used = false;
859 bool is_artificial = false;
860 // Create a move constructor.
861 {
862 CompilerType param_type = t.GetRValueReferenceType();
863 CompilerType function_type =
864 m_ast->CreateFunctionType(return_type, ¶m_type, /*num_params*/ 1,
865 /*variadic=*/false, /*quals*/ 0U);
866 m_ast->AddMethodToCXXRecordType(
867 t.GetOpaqueQualType(), class_name, nullptr, function_type,
868 lldb::AccessType::eAccessPublic, is_virtual, is_static, is_inline,
869 is_explicit, is_attr_used, is_artificial);
870 }
871 // Create a copy constructor.
872 {
873 CompilerType param_type = t.GetLValueReferenceType().AddConstModifier();
874 CompilerType function_type =
875 m_ast->CreateFunctionType(return_type, ¶m_type, /*num_params*/ 1,
876 /*variadic=*/false, /*quals*/ 0U);
877 m_ast->AddMethodToCXXRecordType(
878 t.GetOpaqueQualType(), class_name, nullptr, function_type,
879 lldb::AccessType::eAccessPublic, is_virtual, is_static, is_inline,
880 is_explicit, is_attr_used, is_artificial);
881 }
882
883 // Complete the definition and check the created record.
884 m_ast->CompleteTagDeclarationDefinition(t);
885 auto *record = llvm::cast<CXXRecordDecl>(ClangUtil::GetAsTagDecl(t));
886 EXPECT_TRUE(record->hasUserDeclaredCopyConstructor());
887 }
888
TEST_F(TestTypeSystemClang,AddMethodToObjCObjectType)889 TEST_F(TestTypeSystemClang, AddMethodToObjCObjectType) {
890 // Create an interface decl and mark it as having external storage.
891 CompilerType c = m_ast->CreateObjCClass("A", m_ast->GetTranslationUnitDecl(),
892 OptionalClangModuleID(),
893 /*IsForwardDecl*/ false,
894 /*IsInternal*/ false);
895 ObjCInterfaceDecl *interface = m_ast->GetAsObjCInterfaceDecl(c);
896 m_ast->SetHasExternalStorage(c.GetOpaqueQualType(), true);
897 EXPECT_TRUE(interface->hasExternalLexicalStorage());
898
899 // Add a method to the interface.
900 std::vector<CompilerType> args;
901 CompilerType func_type =
902 m_ast->CreateFunctionType(m_ast->GetBasicType(lldb::eBasicTypeInt),
903 args.data(), args.size(), /*variadic*/ false,
904 /*quals*/ 0, clang::CallingConv::CC_C);
905 bool variadic = false;
906 bool artificial = false;
907 bool objc_direct = false;
908 clang::ObjCMethodDecl *method = TypeSystemClang::AddMethodToObjCObjectType(
909 c, "-[A foo]", func_type, lldb::eAccessPublic, artificial, variadic,
910 objc_direct);
911 ASSERT_NE(method, nullptr);
912
913 // The interface decl should still have external lexical storage.
914 EXPECT_TRUE(interface->hasExternalLexicalStorage());
915
916 // Test some properties of the created ObjCMethodDecl.
917 EXPECT_FALSE(method->isVariadic());
918 EXPECT_TRUE(method->isImplicit());
919 EXPECT_FALSE(method->isDirectMethod());
920 EXPECT_EQ(method->getDeclName().getObjCSelector().getAsString(), "foo");
921 }
922
TEST_F(TestTypeSystemClang,GetFullyUnqualifiedType)923 TEST_F(TestTypeSystemClang, GetFullyUnqualifiedType) {
924 CompilerType bool_ = m_ast->GetBasicType(eBasicTypeBool);
925 CompilerType cv_bool = bool_.AddConstModifier().AddVolatileModifier();
926
927 // const volatile bool -> bool
928 EXPECT_EQ(bool_, cv_bool.GetFullyUnqualifiedType());
929
930 // const volatile bool[47] -> bool[47]
931 EXPECT_EQ(bool_.GetArrayType(47),
932 cv_bool.GetArrayType(47).GetFullyUnqualifiedType());
933
934 // const volatile bool[47][42] -> bool[47][42]
935 EXPECT_EQ(
936 bool_.GetArrayType(42).GetArrayType(47),
937 cv_bool.GetArrayType(42).GetArrayType(47).GetFullyUnqualifiedType());
938
939 // const volatile bool * -> bool *
940 EXPECT_EQ(bool_.GetPointerType(),
941 cv_bool.GetPointerType().GetFullyUnqualifiedType());
942
943 // const volatile bool *[47] -> bool *[47]
944 EXPECT_EQ(
945 bool_.GetPointerType().GetArrayType(47),
946 cv_bool.GetPointerType().GetArrayType(47).GetFullyUnqualifiedType());
947 }
948
TEST(TestScratchTypeSystemClang,InferSubASTFromLangOpts)949 TEST(TestScratchTypeSystemClang, InferSubASTFromLangOpts) {
950 LangOptions lang_opts;
951 EXPECT_EQ(
952 ScratchTypeSystemClang::DefaultAST,
953 ScratchTypeSystemClang::InferIsolatedASTKindFromLangOpts(lang_opts));
954
955 lang_opts.Modules = true;
956 EXPECT_EQ(
957 ScratchTypeSystemClang::IsolatedASTKind::CppModules,
958 ScratchTypeSystemClang::InferIsolatedASTKindFromLangOpts(lang_opts));
959 }
960
TEST_F(TestTypeSystemClang,GetExeModuleWhenMissingSymbolFile)961 TEST_F(TestTypeSystemClang, GetExeModuleWhenMissingSymbolFile) {
962 CompilerType compiler_type = m_ast->GetBasicTypeFromAST(lldb::eBasicTypeInt);
963 lldb_private::Type t(0, nullptr, ConstString("MyType"), llvm::None, nullptr,
964 0, {}, {}, compiler_type,
965 lldb_private::Type::ResolveState::Full);
966 // Test that getting the execution module when no type system is present
967 // is handled gracefully.
968 ModuleSP module = t.GetExeModule();
969 EXPECT_EQ(module.get(), nullptr);
970 }
971
972