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