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 
29   void SetUp() override {
30     m_ast.reset(
31         new TypeSystemClang("test ASTContext", HostInfo::GetTargetTriple()));
32   }
33 
34   void TearDown() override { m_ast.reset(); }
35 
36 protected:
37   std::unique_ptr<TypeSystemClang> m_ast;
38 
39   QualType GetBasicQualType(BasicType type) const {
40     return ClangUtil::GetQualType(m_ast->GetBasicTypeFromAST(type));
41   }
42 
43   QualType GetBasicQualType(const char *name) const {
44     return ClangUtil::GetQualType(
45         m_ast->GetBuiltinTypeByName(ConstString(name)));
46   }
47 };
48 
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 
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 
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 
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 
228 TEST_F(TestTypeSystemClang, TestDisplayName) {
229   TypeSystemClang ast("some name", llvm::Triple());
230   EXPECT_EQ("some name", ast.getDisplayName());
231 }
232 
233 TEST_F(TestTypeSystemClang, TestDisplayNameEmpty) {
234   TypeSystemClang ast("", llvm::Triple());
235   EXPECT_EQ("", ast.getDisplayName());
236 }
237 
238 TEST_F(TestTypeSystemClang, TestGetEnumIntegerTypeInvalid) {
239   EXPECT_FALSE(m_ast->GetEnumerationIntegerType(CompilerType()).IsValid());
240 }
241 
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 
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 
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 
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 
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 
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 
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 
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 
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     EXPECT_EQ(m_ast->GetTemplateArgumentKind(t.GetOpaqueQualType(), 0),
504               eTemplateArgumentKindType);
505     EXPECT_EQ(m_ast->GetTypeTemplateArgument(t.GetOpaqueQualType(), 0),
506               int_type);
507     EXPECT_EQ(llvm::None,
508               m_ast->GetIntegralTemplateArgument(t.GetOpaqueQualType(), 0));
509 
510     EXPECT_EQ(m_ast->GetTemplateArgumentKind(t.GetOpaqueQualType(), 1),
511               eTemplateArgumentKindIntegral);
512     EXPECT_EQ(m_ast->GetTypeTemplateArgument(t.GetOpaqueQualType(), 1),
513               CompilerType());
514     auto result = m_ast->GetIntegralTemplateArgument(t.GetOpaqueQualType(), 1);
515     ASSERT_NE(llvm::None, result);
516     EXPECT_EQ(arg, result->value);
517     EXPECT_EQ(int_type, result->type);
518   }
519 }
520 
521 class TestCreateClassTemplateDecl : public TestTypeSystemClang {
522 protected:
523   /// The class templates created so far by the Expect* functions below.
524   llvm::DenseSet<ClassTemplateDecl *> m_created_templates;
525 
526   /// Utility function for creating a class template.
527   ClassTemplateDecl *
528   CreateClassTemplate(const TypeSystemClang::TemplateParameterInfos &infos) {
529     ClassTemplateDecl *decl = m_ast->CreateClassTemplateDecl(
530         m_ast->GetTranslationUnitDecl(), OptionalClangModuleID(), eAccessPublic,
531         "foo", TTK_Struct, infos);
532     return decl;
533   }
534 
535   /// Creates a new class template with the given template parameters.
536   /// Asserts that a new ClassTemplateDecl is created.
537   /// \param description The gtest scope string that should describe the input.
538   /// \param infos The template parameters that the class template should have.
539   /// \returns The created ClassTemplateDecl.
540   ClassTemplateDecl *
541   ExpectNewTemplate(std::string description,
542                     const TypeSystemClang::TemplateParameterInfos &infos) {
543     SCOPED_TRACE(description);
544     ClassTemplateDecl *first_template = CreateClassTemplate(infos);
545     // A new template should have been created.
546     EXPECT_FALSE(m_created_templates.contains(first_template))
547         << "Didn't create new class template but reused this existing decl:\n"
548         << ClangUtil::DumpDecl(first_template);
549     m_created_templates.insert(first_template);
550 
551     // Creating a new template with the same arguments should always return
552     // the template created above.
553     ClassTemplateDecl *second_template = CreateClassTemplate(infos);
554     EXPECT_EQ(first_template, second_template)
555         << "Second attempt to create class template didn't reuse first decl:\n"
556         << ClangUtil::DumpDecl(first_template) << "\nInstead created/reused:\n"
557         << ClangUtil::DumpDecl(second_template);
558     return first_template;
559   }
560 
561   /// Tries to create a new class template but asserts that an existing class
562   /// template in the current AST is reused (in contract so a new class
563   /// template being created).
564   /// \param description The gtest scope string that should describe the input.
565   /// \param infos The template parameters that the class template should have.
566   void
567   ExpectReusedTemplate(std::string description,
568                        const TypeSystemClang::TemplateParameterInfos &infos,
569                        ClassTemplateDecl *expected) {
570     SCOPED_TRACE(description);
571     ClassTemplateDecl *td = CreateClassTemplate(infos);
572     EXPECT_EQ(td, expected)
573         << "Created/reused class template is:\n"
574         << ClangUtil::DumpDecl(td) << "\nExpected to reuse:\n"
575         << ClangUtil::DumpDecl(expected);
576   }
577 };
578 
579 TEST_F(TestCreateClassTemplateDecl, FindExistingTemplates) {
580   // This tests the logic in TypeSystemClang::CreateClassTemplateDecl that
581   // decides whether an existing ClassTemplateDecl in the AST can be reused.
582   // The behaviour should follow the C++ rules for redeclaring templates
583   // (e.g., parameter names can be changed/omitted.)
584 
585   // This describes a class template *instantiation* from which we will infer
586   // the structure of the class template.
587   TypeSystemClang::TemplateParameterInfos infos;
588 
589   // Test an empty template parameter list: <>
590   ExpectNewTemplate("<>", infos);
591 
592   // Test that <typename T> with T = int creates a new template.
593   infos.names = {"T"};
594   infos.args = {TemplateArgument(m_ast->getASTContext().IntTy)};
595   ClassTemplateDecl *single_type_arg = ExpectNewTemplate("<typename T>", infos);
596 
597   // Test that changing the parameter name doesn't create a new class template.
598   infos.names = {"A"};
599   ExpectReusedTemplate("<typename A> (A = int)", infos, single_type_arg);
600 
601   // Test that changing the used type doesn't create a new class template.
602   infos.args = {TemplateArgument(m_ast->getASTContext().FloatTy)};
603   ExpectReusedTemplate("<typename A> (A = float)", infos, single_type_arg);
604 
605   // Test that <typename A, signed char I> creates a new template with A = int
606   // and I = 47;
607   infos.names.push_back("I");
608   infos.args.push_back(TemplateArgument(m_ast->getASTContext(),
609                                         llvm::APSInt(llvm::APInt(8, 47)),
610                                         m_ast->getASTContext().SignedCharTy));
611   ClassTemplateDecl *type_and_char_value =
612       ExpectNewTemplate("<typename A, signed char I> (I = 47)", infos);
613 
614   // Change the value of the I parameter to 123. The previously created
615   // class template should still be reused.
616   infos.args.pop_back();
617   infos.args.push_back(TemplateArgument(m_ast->getASTContext(),
618                                         llvm::APSInt(llvm::APInt(8, 123)),
619                                         m_ast->getASTContext().SignedCharTy));
620   ExpectReusedTemplate("<typename A, signed char I> (I = 123)", infos,
621                        type_and_char_value);
622 
623   // Change the type of the I parameter to int so we have <typename A, int I>.
624   // The class template from above can't be reused.
625   infos.args.pop_back();
626   infos.args.push_back(TemplateArgument(m_ast->getASTContext(),
627                                         llvm::APSInt(llvm::APInt(32, 47)),
628                                         m_ast->getASTContext().IntTy));
629   ExpectNewTemplate("<typename A, int I> (I = 123)", infos);
630 
631   // Test a second type parameter will also cause a new template to be created.
632   // We now have <typename A, int I, typename B>.
633   infos.names.push_back("B");
634   infos.args.push_back(TemplateArgument(m_ast->getASTContext().IntTy));
635   ClassTemplateDecl *type_and_char_value_and_type =
636       ExpectNewTemplate("<typename A, int I, typename B>", infos);
637 
638   // Remove all the names from the parameters which shouldn't influence the
639   // way the templates get merged.
640   infos.names = {"", "", ""};
641   ExpectReusedTemplate("<typename, int, typename>", infos,
642                        type_and_char_value_and_type);
643 }
644 
645 TEST_F(TestCreateClassTemplateDecl, FindExistingTemplatesWithParameterPack) {
646   // The same as FindExistingTemplates but for templates with parameter packs.
647 
648   TypeSystemClang::TemplateParameterInfos infos;
649   infos.packed_args =
650       std::make_unique<TypeSystemClang::TemplateParameterInfos>();
651   infos.packed_args->names = {"", ""};
652   infos.packed_args->args = {TemplateArgument(m_ast->getASTContext().IntTy),
653                              TemplateArgument(m_ast->getASTContext().IntTy)};
654   ClassTemplateDecl *type_pack =
655       ExpectNewTemplate("<typename ...> (int, int)", infos);
656 
657   // Special case: An instantiation for a parameter pack with no values fits
658   // to whatever class template we find. There isn't enough information to
659   // do an actual comparison here.
660   infos.packed_args =
661       std::make_unique<TypeSystemClang::TemplateParameterInfos>();
662   ExpectReusedTemplate("<...> (no values in pack)", infos, type_pack);
663 
664   // Change the type content of pack type values.
665   infos.packed_args->names = {"", ""};
666   infos.packed_args->args = {TemplateArgument(m_ast->getASTContext().IntTy),
667                              TemplateArgument(m_ast->getASTContext().LongTy)};
668   ExpectReusedTemplate("<typename ...> (int, long)", infos, type_pack);
669 
670   // Change the number of pack values.
671   infos.packed_args->args = {TemplateArgument(m_ast->getASTContext().IntTy)};
672   ExpectReusedTemplate("<typename ...> (int)", infos, type_pack);
673 
674   // The names of the pack values shouldn't matter.
675   infos.packed_args->names = {"A", "B"};
676   ExpectReusedTemplate("<typename ...> (int)", infos, type_pack);
677 
678   // Changing the kind of template argument will create a new template.
679   infos.packed_args->args = {TemplateArgument(m_ast->getASTContext(),
680                                               llvm::APSInt(llvm::APInt(32, 1)),
681                                               m_ast->getASTContext().IntTy)};
682   ClassTemplateDecl *int_pack = ExpectNewTemplate("<int ...> (int = 1)", infos);
683 
684   // Changing the value of integral parameters will not create a new template.
685   infos.packed_args->args = {TemplateArgument(
686       m_ast->getASTContext(), llvm::APSInt(llvm::APInt(32, 123)),
687       m_ast->getASTContext().IntTy)};
688   ExpectReusedTemplate("<int ...> (int = 123)", infos, int_pack);
689 
690   // Changing the integral type will create a new template.
691   infos.packed_args->args = {TemplateArgument(m_ast->getASTContext(),
692                                               llvm::APSInt(llvm::APInt(64, 1)),
693                                               m_ast->getASTContext().LongTy)};
694   ExpectNewTemplate("<long ...> (long = 1)", infos);
695 
696   // Prependinding a non-pack parameter will create a new template.
697   infos.names = {"T"};
698   infos.args = {TemplateArgument(m_ast->getASTContext().IntTy)};
699   ExpectNewTemplate("<typename T, long...> (T = int, long = 1)", infos);
700 }
701 
702 TEST_F(TestTypeSystemClang, OnlyPackName) {
703   TypeSystemClang::TemplateParameterInfos infos;
704   infos.pack_name = "A";
705   EXPECT_FALSE(infos.IsValid());
706 }
707 
708 static QualType makeConstInt(clang::ASTContext &ctxt) {
709   QualType result(ctxt.IntTy);
710   result.addConst();
711   return result;
712 }
713 
714 TEST_F(TestTypeSystemClang, TestGetTypeClassDeclType) {
715   clang::ASTContext &ctxt = m_ast->getASTContext();
716   auto *nullptr_expr = new (ctxt) CXXNullPtrLiteralExpr(ctxt.NullPtrTy, SourceLocation());
717   QualType t = ctxt.getDecltypeType(nullptr_expr, makeConstInt(ctxt));
718   EXPECT_EQ(lldb::eTypeClassBuiltin, m_ast->GetTypeClass(t.getAsOpaquePtr()));
719 }
720 
721 TEST_F(TestTypeSystemClang, TestGetTypeClassTypeOf) {
722   clang::ASTContext &ctxt = m_ast->getASTContext();
723   QualType t = ctxt.getTypeOfType(makeConstInt(ctxt));
724   EXPECT_EQ(lldb::eTypeClassBuiltin, m_ast->GetTypeClass(t.getAsOpaquePtr()));
725 }
726 
727 TEST_F(TestTypeSystemClang, TestGetTypeClassTypeOfExpr) {
728   clang::ASTContext &ctxt = m_ast->getASTContext();
729   auto *nullptr_expr = new (ctxt) CXXNullPtrLiteralExpr(ctxt.NullPtrTy, SourceLocation());
730   QualType t = ctxt.getTypeOfExprType(nullptr_expr);
731   EXPECT_EQ(lldb::eTypeClassBuiltin, m_ast->GetTypeClass(t.getAsOpaquePtr()));
732 }
733 
734 TEST_F(TestTypeSystemClang, TestGetTypeClassNested) {
735   clang::ASTContext &ctxt = m_ast->getASTContext();
736   QualType t_base = ctxt.getTypeOfType(makeConstInt(ctxt));
737   QualType t = ctxt.getTypeOfType(t_base);
738   EXPECT_EQ(lldb::eTypeClassBuiltin, m_ast->GetTypeClass(t.getAsOpaquePtr()));
739 }
740 
741 TEST_F(TestTypeSystemClang, TestFunctionTemplateConstruction) {
742   // Tests creating a function template.
743 
744   CompilerType int_type = m_ast->GetBasicType(lldb::eBasicTypeInt);
745   clang::TranslationUnitDecl *TU = m_ast->GetTranslationUnitDecl();
746 
747   // Prepare the declarations/types we need for the template.
748   CompilerType clang_type =
749       m_ast->CreateFunctionType(int_type, nullptr, 0U, false, 0U);
750   FunctionDecl *func = m_ast->CreateFunctionDeclaration(
751       TU, OptionalClangModuleID(), "foo", clang_type, StorageClass::SC_None,
752       false);
753   TypeSystemClang::TemplateParameterInfos empty_params;
754 
755   // Create the actual function template.
756   clang::FunctionTemplateDecl *func_template =
757       m_ast->CreateFunctionTemplateDecl(TU, OptionalClangModuleID(), func,
758                                         empty_params);
759 
760   EXPECT_EQ(TU, func_template->getDeclContext());
761   EXPECT_EQ("foo", func_template->getName());
762   EXPECT_EQ(clang::AccessSpecifier::AS_none, func_template->getAccess());
763 }
764 
765 TEST_F(TestTypeSystemClang, TestFunctionTemplateInRecordConstruction) {
766   // Tests creating a function template inside a record.
767 
768   CompilerType int_type = m_ast->GetBasicType(lldb::eBasicTypeInt);
769   clang::TranslationUnitDecl *TU = m_ast->GetTranslationUnitDecl();
770 
771   // Create a record we can put the function template int.
772   CompilerType record_type =
773       clang_utils::createRecordWithField(*m_ast, "record", int_type, "field");
774   clang::TagDecl *record = ClangUtil::GetAsTagDecl(record_type);
775 
776   // Prepare the declarations/types we need for the template.
777   CompilerType clang_type =
778       m_ast->CreateFunctionType(int_type, nullptr, 0U, false, 0U);
779   // We create the FunctionDecl for the template in the TU DeclContext because:
780   // 1. FunctionDecls can't be in a Record (only CXXMethodDecls can).
781   // 2. It is mirroring the behavior of DWARFASTParserClang::ParseSubroutine.
782   FunctionDecl *func = m_ast->CreateFunctionDeclaration(
783       TU, OptionalClangModuleID(), "foo", clang_type, StorageClass::SC_None,
784       false);
785   TypeSystemClang::TemplateParameterInfos empty_params;
786 
787   // Create the actual function template.
788   clang::FunctionTemplateDecl *func_template =
789       m_ast->CreateFunctionTemplateDecl(record, OptionalClangModuleID(), func,
790                                         empty_params);
791 
792   EXPECT_EQ(record, func_template->getDeclContext());
793   EXPECT_EQ("foo", func_template->getName());
794   EXPECT_EQ(clang::AccessSpecifier::AS_public, func_template->getAccess());
795 }
796 
797 TEST_F(TestTypeSystemClang, TestDeletingImplicitCopyCstrDueToMoveCStr) {
798   // We need to simulate this behavior in our AST that we construct as we don't
799   // have a Sema instance that can do this for us:
800   // C++11 [class.copy]p7, p18:
801   //  If the class definition declares a move constructor or move assignment
802   //  operator, an implicitly declared copy constructor or copy assignment
803   //  operator is defined as deleted.
804 
805   // Create a record and start defining it.
806   llvm::StringRef class_name = "S";
807   CompilerType t = clang_utils::createRecord(*m_ast, class_name);
808   m_ast->StartTagDeclarationDefinition(t);
809 
810   // Create a move constructor that will delete the implicit copy constructor.
811   CompilerType return_type = m_ast->GetBasicType(lldb::eBasicTypeVoid);
812   CompilerType param_type = t.GetRValueReferenceType();
813   CompilerType function_type =
814       m_ast->CreateFunctionType(return_type, &param_type, /*num_params*/ 1,
815                                 /*variadic=*/false, /*quals*/ 0U);
816   bool is_virtual = false;
817   bool is_static = false;
818   bool is_inline = false;
819   bool is_explicit = true;
820   bool is_attr_used = false;
821   bool is_artificial = false;
822   m_ast->AddMethodToCXXRecordType(
823       t.GetOpaqueQualType(), class_name, nullptr, function_type,
824       lldb::AccessType::eAccessPublic, is_virtual, is_static, is_inline,
825       is_explicit, is_attr_used, is_artificial);
826 
827   // Complete the definition and check the created record.
828   m_ast->CompleteTagDeclarationDefinition(t);
829   auto *record = llvm::cast<CXXRecordDecl>(ClangUtil::GetAsTagDecl(t));
830   // We can't call defaultedCopyConstructorIsDeleted() as this requires that
831   // the Decl passes through Sema which will actually compute this field.
832   // Instead we check that there is no copy constructor declared by the user
833   // which only leaves a non-deleted defaulted copy constructor as an option
834   // that our record will have no simple copy constructor.
835   EXPECT_FALSE(record->hasUserDeclaredCopyConstructor());
836   EXPECT_FALSE(record->hasSimpleCopyConstructor());
837 }
838 
839 TEST_F(TestTypeSystemClang, TestNotDeletingUserCopyCstrDueToMoveCStr) {
840   // Tests that we don't delete the a user-defined copy constructor when
841   // a move constructor is provided.
842   // See also the TestDeletingImplicitCopyCstrDueToMoveCStr test.
843   llvm::StringRef class_name = "S";
844   CompilerType t = clang_utils::createRecord(*m_ast, class_name);
845   m_ast->StartTagDeclarationDefinition(t);
846 
847   CompilerType return_type = m_ast->GetBasicType(lldb::eBasicTypeVoid);
848   bool is_virtual = false;
849   bool is_static = false;
850   bool is_inline = false;
851   bool is_explicit = true;
852   bool is_attr_used = false;
853   bool is_artificial = false;
854   // Create a move constructor.
855   {
856     CompilerType param_type = t.GetRValueReferenceType();
857     CompilerType function_type =
858         m_ast->CreateFunctionType(return_type, &param_type, /*num_params*/ 1,
859                                   /*variadic=*/false, /*quals*/ 0U);
860     m_ast->AddMethodToCXXRecordType(
861         t.GetOpaqueQualType(), class_name, nullptr, function_type,
862         lldb::AccessType::eAccessPublic, is_virtual, is_static, is_inline,
863         is_explicit, is_attr_used, is_artificial);
864   }
865   // Create a copy constructor.
866   {
867     CompilerType param_type = t.GetLValueReferenceType().AddConstModifier();
868     CompilerType function_type =
869         m_ast->CreateFunctionType(return_type, &param_type, /*num_params*/ 1,
870                                   /*variadic=*/false, /*quals*/ 0U);
871     m_ast->AddMethodToCXXRecordType(
872         t.GetOpaqueQualType(), class_name, nullptr, function_type,
873         lldb::AccessType::eAccessPublic, is_virtual, is_static, is_inline,
874         is_explicit, is_attr_used, is_artificial);
875   }
876 
877   // Complete the definition and check the created record.
878   m_ast->CompleteTagDeclarationDefinition(t);
879   auto *record = llvm::cast<CXXRecordDecl>(ClangUtil::GetAsTagDecl(t));
880   EXPECT_TRUE(record->hasUserDeclaredCopyConstructor());
881 }
882 
883 TEST_F(TestTypeSystemClang, AddMethodToObjCObjectType) {
884   // Create an interface decl and mark it as having external storage.
885   CompilerType c = m_ast->CreateObjCClass("A", m_ast->GetTranslationUnitDecl(),
886                                           OptionalClangModuleID(),
887                                           /*IsForwardDecl*/ false,
888                                           /*IsInternal*/ false);
889   ObjCInterfaceDecl *interface = m_ast->GetAsObjCInterfaceDecl(c);
890   m_ast->SetHasExternalStorage(c.GetOpaqueQualType(), true);
891   EXPECT_TRUE(interface->hasExternalLexicalStorage());
892 
893   // Add a method to the interface.
894   std::vector<CompilerType> args;
895   CompilerType func_type =
896       m_ast->CreateFunctionType(m_ast->GetBasicType(lldb::eBasicTypeInt),
897                                 args.data(), args.size(), /*variadic*/ false,
898                                 /*quals*/ 0, clang::CallingConv::CC_C);
899   bool variadic = false;
900   bool artificial = false;
901   bool objc_direct = false;
902   clang::ObjCMethodDecl *method = TypeSystemClang::AddMethodToObjCObjectType(
903       c, "-[A foo]", func_type, lldb::eAccessPublic, artificial, variadic,
904       objc_direct);
905   ASSERT_NE(method, nullptr);
906 
907   // The interface decl should still have external lexical storage.
908   EXPECT_TRUE(interface->hasExternalLexicalStorage());
909 
910   // Test some properties of the created ObjCMethodDecl.
911   EXPECT_FALSE(method->isVariadic());
912   EXPECT_TRUE(method->isImplicit());
913   EXPECT_FALSE(method->isDirectMethod());
914   EXPECT_EQ(method->getDeclName().getObjCSelector().getAsString(), "foo");
915 }
916 
917 TEST_F(TestTypeSystemClang, GetFullyUnqualifiedType) {
918   CompilerType bool_ = m_ast->GetBasicType(eBasicTypeBool);
919   CompilerType cv_bool = bool_.AddConstModifier().AddVolatileModifier();
920 
921   // const volatile bool -> bool
922   EXPECT_EQ(bool_, cv_bool.GetFullyUnqualifiedType());
923 
924   // const volatile bool[47] -> bool[47]
925   EXPECT_EQ(bool_.GetArrayType(47),
926             cv_bool.GetArrayType(47).GetFullyUnqualifiedType());
927 
928   // const volatile bool[47][42] -> bool[47][42]
929   EXPECT_EQ(
930       bool_.GetArrayType(42).GetArrayType(47),
931       cv_bool.GetArrayType(42).GetArrayType(47).GetFullyUnqualifiedType());
932 
933   // const volatile bool * -> bool *
934   EXPECT_EQ(bool_.GetPointerType(),
935             cv_bool.GetPointerType().GetFullyUnqualifiedType());
936 
937   // const volatile bool *[47] -> bool *[47]
938   EXPECT_EQ(
939       bool_.GetPointerType().GetArrayType(47),
940       cv_bool.GetPointerType().GetArrayType(47).GetFullyUnqualifiedType());
941 }
942 
943 TEST(TestScratchTypeSystemClang, InferSubASTFromLangOpts) {
944   LangOptions lang_opts;
945   EXPECT_EQ(
946       ScratchTypeSystemClang::DefaultAST,
947       ScratchTypeSystemClang::InferIsolatedASTKindFromLangOpts(lang_opts));
948 
949   lang_opts.Modules = true;
950   EXPECT_EQ(
951       ScratchTypeSystemClang::IsolatedASTKind::CppModules,
952       ScratchTypeSystemClang::InferIsolatedASTKindFromLangOpts(lang_opts));
953 }
954 
955 TEST_F(TestTypeSystemClang, GetExeModuleWhenMissingSymbolFile) {
956   CompilerType compiler_type = m_ast->GetBasicTypeFromAST(lldb::eBasicTypeInt);
957   lldb_private::Type t(0, nullptr, ConstString("MyType"), llvm::None, nullptr,
958                        0, {}, {}, compiler_type,
959                        lldb_private::Type::ResolveState::Full);
960   // Test that getting the execution module when no type system is present
961   // is handled gracefully.
962   ModuleSP module = t.GetExeModule();
963   EXPECT_EQ(module.get(), nullptr);
964 }
965 
966