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