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