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, &param_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, &param_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, &param_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