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/Host/FileSystem.h"
14 #include "lldb/Host/HostInfo.h"
15 #include "lldb/Symbol/Declaration.h"
16 #include "clang/AST/DeclCXX.h"
17 #include "clang/AST/ExprCXX.h"
18 #include "gtest/gtest.h"
19 
20 using namespace clang;
21 using namespace lldb;
22 using namespace lldb_private;
23 
24 class TestTypeSystemClang : public testing::Test {
25 public:
26   SubsystemRAII<FileSystem, HostInfo> subsystems;
27 
28   void SetUp() override {
29     m_ast.reset(
30         new TypeSystemClang("test ASTContext", HostInfo::GetTargetTriple()));
31   }
32 
33   void TearDown() override { m_ast.reset(); }
34 
35 protected:
36   std::unique_ptr<TypeSystemClang> m_ast;
37 
38   QualType GetBasicQualType(BasicType type) const {
39     return ClangUtil::GetQualType(m_ast->GetBasicTypeFromAST(type));
40   }
41 
42   QualType GetBasicQualType(const char *name) const {
43     return ClangUtil::GetQualType(
44         m_ast->GetBuiltinTypeByName(ConstString(name)));
45   }
46 };
47 
48 TEST_F(TestTypeSystemClang, TestGetBasicTypeFromEnum) {
49   clang::ASTContext &context = m_ast->getASTContext();
50 
51   EXPECT_TRUE(
52       context.hasSameType(GetBasicQualType(eBasicTypeBool), context.BoolTy));
53   EXPECT_TRUE(
54       context.hasSameType(GetBasicQualType(eBasicTypeChar), context.CharTy));
55   EXPECT_TRUE(context.hasSameType(GetBasicQualType(eBasicTypeChar16),
56                                   context.Char16Ty));
57   EXPECT_TRUE(context.hasSameType(GetBasicQualType(eBasicTypeChar32),
58                                   context.Char32Ty));
59   EXPECT_TRUE(context.hasSameType(GetBasicQualType(eBasicTypeDouble),
60                                   context.DoubleTy));
61   EXPECT_TRUE(context.hasSameType(GetBasicQualType(eBasicTypeDoubleComplex),
62                                   context.DoubleComplexTy));
63   EXPECT_TRUE(
64       context.hasSameType(GetBasicQualType(eBasicTypeFloat), context.FloatTy));
65   EXPECT_TRUE(context.hasSameType(GetBasicQualType(eBasicTypeFloatComplex),
66                                   context.FloatComplexTy));
67   EXPECT_TRUE(
68       context.hasSameType(GetBasicQualType(eBasicTypeHalf), context.HalfTy));
69   EXPECT_TRUE(
70       context.hasSameType(GetBasicQualType(eBasicTypeInt), context.IntTy));
71   EXPECT_TRUE(context.hasSameType(GetBasicQualType(eBasicTypeInt128),
72                                   context.Int128Ty));
73   EXPECT_TRUE(
74       context.hasSameType(GetBasicQualType(eBasicTypeLong), context.LongTy));
75   EXPECT_TRUE(context.hasSameType(GetBasicQualType(eBasicTypeLongDouble),
76                                   context.LongDoubleTy));
77   EXPECT_TRUE(context.hasSameType(GetBasicQualType(eBasicTypeLongDoubleComplex),
78                                   context.LongDoubleComplexTy));
79   EXPECT_TRUE(context.hasSameType(GetBasicQualType(eBasicTypeLongLong),
80                                   context.LongLongTy));
81   EXPECT_TRUE(context.hasSameType(GetBasicQualType(eBasicTypeNullPtr),
82                                   context.NullPtrTy));
83   EXPECT_TRUE(context.hasSameType(GetBasicQualType(eBasicTypeObjCClass),
84                                   context.getObjCClassType()));
85   EXPECT_TRUE(context.hasSameType(GetBasicQualType(eBasicTypeObjCID),
86                                   context.getObjCIdType()));
87   EXPECT_TRUE(context.hasSameType(GetBasicQualType(eBasicTypeObjCSel),
88                                   context.getObjCSelType()));
89   EXPECT_TRUE(
90       context.hasSameType(GetBasicQualType(eBasicTypeShort), context.ShortTy));
91   EXPECT_TRUE(context.hasSameType(GetBasicQualType(eBasicTypeSignedChar),
92                                   context.SignedCharTy));
93   EXPECT_TRUE(context.hasSameType(GetBasicQualType(eBasicTypeUnsignedChar),
94                                   context.UnsignedCharTy));
95   EXPECT_TRUE(context.hasSameType(GetBasicQualType(eBasicTypeUnsignedInt),
96                                   context.UnsignedIntTy));
97   EXPECT_TRUE(context.hasSameType(GetBasicQualType(eBasicTypeUnsignedInt128),
98                                   context.UnsignedInt128Ty));
99   EXPECT_TRUE(context.hasSameType(GetBasicQualType(eBasicTypeUnsignedLong),
100                                   context.UnsignedLongTy));
101   EXPECT_TRUE(context.hasSameType(GetBasicQualType(eBasicTypeUnsignedLongLong),
102                                   context.UnsignedLongLongTy));
103   EXPECT_TRUE(context.hasSameType(GetBasicQualType(eBasicTypeUnsignedShort),
104                                   context.UnsignedShortTy));
105   EXPECT_TRUE(
106       context.hasSameType(GetBasicQualType(eBasicTypeVoid), context.VoidTy));
107   EXPECT_TRUE(
108       context.hasSameType(GetBasicQualType(eBasicTypeWChar), context.WCharTy));
109 }
110 
111 TEST_F(TestTypeSystemClang, TestGetBasicTypeFromName) {
112   EXPECT_EQ(GetBasicQualType(eBasicTypeChar), GetBasicQualType("char"));
113   EXPECT_EQ(GetBasicQualType(eBasicTypeSignedChar),
114             GetBasicQualType("signed char"));
115   EXPECT_EQ(GetBasicQualType(eBasicTypeUnsignedChar),
116             GetBasicQualType("unsigned char"));
117   EXPECT_EQ(GetBasicQualType(eBasicTypeWChar), GetBasicQualType("wchar_t"));
118   EXPECT_EQ(GetBasicQualType(eBasicTypeSignedWChar),
119             GetBasicQualType("signed wchar_t"));
120   EXPECT_EQ(GetBasicQualType(eBasicTypeUnsignedWChar),
121             GetBasicQualType("unsigned wchar_t"));
122   EXPECT_EQ(GetBasicQualType(eBasicTypeShort), GetBasicQualType("short"));
123   EXPECT_EQ(GetBasicQualType(eBasicTypeShort), GetBasicQualType("short int"));
124   EXPECT_EQ(GetBasicQualType(eBasicTypeUnsignedShort),
125             GetBasicQualType("unsigned short"));
126   EXPECT_EQ(GetBasicQualType(eBasicTypeUnsignedShort),
127             GetBasicQualType("unsigned short int"));
128   EXPECT_EQ(GetBasicQualType(eBasicTypeInt), GetBasicQualType("int"));
129   EXPECT_EQ(GetBasicQualType(eBasicTypeInt), GetBasicQualType("signed int"));
130   EXPECT_EQ(GetBasicQualType(eBasicTypeUnsignedInt),
131             GetBasicQualType("unsigned int"));
132   EXPECT_EQ(GetBasicQualType(eBasicTypeUnsignedInt),
133             GetBasicQualType("unsigned"));
134   EXPECT_EQ(GetBasicQualType(eBasicTypeLong), GetBasicQualType("long"));
135   EXPECT_EQ(GetBasicQualType(eBasicTypeLong), GetBasicQualType("long int"));
136   EXPECT_EQ(GetBasicQualType(eBasicTypeUnsignedLong),
137             GetBasicQualType("unsigned long"));
138   EXPECT_EQ(GetBasicQualType(eBasicTypeUnsignedLong),
139             GetBasicQualType("unsigned long int"));
140   EXPECT_EQ(GetBasicQualType(eBasicTypeLongLong),
141             GetBasicQualType("long long"));
142   EXPECT_EQ(GetBasicQualType(eBasicTypeLongLong),
143             GetBasicQualType("long long int"));
144   EXPECT_EQ(GetBasicQualType(eBasicTypeUnsignedLongLong),
145             GetBasicQualType("unsigned long long"));
146   EXPECT_EQ(GetBasicQualType(eBasicTypeUnsignedLongLong),
147             GetBasicQualType("unsigned long long int"));
148   EXPECT_EQ(GetBasicQualType(eBasicTypeInt128), GetBasicQualType("__int128_t"));
149   EXPECT_EQ(GetBasicQualType(eBasicTypeUnsignedInt128),
150             GetBasicQualType("__uint128_t"));
151   EXPECT_EQ(GetBasicQualType(eBasicTypeVoid), GetBasicQualType("void"));
152   EXPECT_EQ(GetBasicQualType(eBasicTypeBool), GetBasicQualType("bool"));
153   EXPECT_EQ(GetBasicQualType(eBasicTypeFloat), GetBasicQualType("float"));
154   EXPECT_EQ(GetBasicQualType(eBasicTypeDouble), GetBasicQualType("double"));
155   EXPECT_EQ(GetBasicQualType(eBasicTypeLongDouble),
156             GetBasicQualType("long double"));
157   EXPECT_EQ(GetBasicQualType(eBasicTypeObjCID), GetBasicQualType("id"));
158   EXPECT_EQ(GetBasicQualType(eBasicTypeObjCSel), GetBasicQualType("SEL"));
159   EXPECT_EQ(GetBasicQualType(eBasicTypeNullPtr), GetBasicQualType("nullptr"));
160 }
161 
162 void VerifyEncodingAndBitSize(TypeSystemClang &clang_context,
163                               lldb::Encoding encoding, unsigned int bit_size) {
164   clang::ASTContext &context = clang_context.getASTContext();
165 
166   CompilerType type =
167       clang_context.GetBuiltinTypeForEncodingAndBitSize(encoding, bit_size);
168   EXPECT_TRUE(type.IsValid());
169 
170   QualType qtype = ClangUtil::GetQualType(type);
171   EXPECT_FALSE(qtype.isNull());
172   if (qtype.isNull())
173     return;
174 
175   uint64_t actual_size = context.getTypeSize(qtype);
176   EXPECT_EQ(bit_size, actual_size);
177 
178   const clang::Type *type_ptr = qtype.getTypePtr();
179   EXPECT_NE(nullptr, type_ptr);
180   if (!type_ptr)
181     return;
182 
183   EXPECT_TRUE(type_ptr->isBuiltinType());
184   switch (encoding) {
185   case eEncodingSint:
186     EXPECT_TRUE(type_ptr->isSignedIntegerType());
187     break;
188   case eEncodingUint:
189     EXPECT_TRUE(type_ptr->isUnsignedIntegerType());
190     break;
191   case eEncodingIEEE754:
192     EXPECT_TRUE(type_ptr->isFloatingType());
193     break;
194   default:
195     FAIL() << "Unexpected encoding";
196     break;
197   }
198 }
199 
200 TEST_F(TestTypeSystemClang, TestBuiltinTypeForEncodingAndBitSize) {
201   // Make sure we can get types of every possible size in every possible
202   // encoding.
203   // We can't make any guarantee about which specific type we get, because the
204   // standard
205   // isn't that specific.  We only need to make sure the compiler hands us some
206   // type that
207   // is both a builtin type and matches the requested bit size.
208   VerifyEncodingAndBitSize(*m_ast, eEncodingSint, 8);
209   VerifyEncodingAndBitSize(*m_ast, eEncodingSint, 16);
210   VerifyEncodingAndBitSize(*m_ast, eEncodingSint, 32);
211   VerifyEncodingAndBitSize(*m_ast, eEncodingSint, 64);
212   VerifyEncodingAndBitSize(*m_ast, eEncodingSint, 128);
213 
214   VerifyEncodingAndBitSize(*m_ast, eEncodingUint, 8);
215   VerifyEncodingAndBitSize(*m_ast, eEncodingUint, 16);
216   VerifyEncodingAndBitSize(*m_ast, eEncodingUint, 32);
217   VerifyEncodingAndBitSize(*m_ast, eEncodingUint, 64);
218   VerifyEncodingAndBitSize(*m_ast, eEncodingUint, 128);
219 
220   VerifyEncodingAndBitSize(*m_ast, eEncodingIEEE754, 32);
221   VerifyEncodingAndBitSize(*m_ast, eEncodingIEEE754, 64);
222 }
223 
224 TEST_F(TestTypeSystemClang, TestDisplayName) {
225   TypeSystemClang ast("some name", llvm::Triple());
226   EXPECT_EQ("some name", ast.getDisplayName());
227 }
228 
229 TEST_F(TestTypeSystemClang, TestDisplayNameEmpty) {
230   TypeSystemClang ast("", llvm::Triple());
231   EXPECT_EQ("", ast.getDisplayName());
232 }
233 
234 TEST_F(TestTypeSystemClang, TestIsClangType) {
235   clang::ASTContext &context = m_ast->getASTContext();
236   lldb::opaque_compiler_type_t bool_ctype =
237       TypeSystemClang::GetOpaqueCompilerType(&context, lldb::eBasicTypeBool);
238   CompilerType bool_type(m_ast.get(), bool_ctype);
239   CompilerType record_type = m_ast->CreateRecordType(
240       nullptr, lldb::eAccessPublic, "FooRecord", clang::TTK_Struct,
241       lldb::eLanguageTypeC_plus_plus, nullptr);
242   // Clang builtin type and record type should pass
243   EXPECT_TRUE(ClangUtil::IsClangType(bool_type));
244   EXPECT_TRUE(ClangUtil::IsClangType(record_type));
245 
246   // Default constructed type should fail
247   EXPECT_FALSE(ClangUtil::IsClangType(CompilerType()));
248 }
249 
250 TEST_F(TestTypeSystemClang, TestRemoveFastQualifiers) {
251   CompilerType record_type = m_ast->CreateRecordType(
252       nullptr, lldb::eAccessPublic, "FooRecord", clang::TTK_Struct,
253       lldb::eLanguageTypeC_plus_plus, nullptr);
254   QualType qt;
255 
256   qt = ClangUtil::GetQualType(record_type);
257   EXPECT_EQ(0u, qt.getLocalFastQualifiers());
258   record_type = record_type.AddConstModifier();
259   record_type = record_type.AddVolatileModifier();
260   record_type = record_type.AddRestrictModifier();
261   qt = ClangUtil::GetQualType(record_type);
262   EXPECT_NE(0u, qt.getLocalFastQualifiers());
263   record_type = ClangUtil::RemoveFastQualifiers(record_type);
264   qt = ClangUtil::GetQualType(record_type);
265   EXPECT_EQ(0u, qt.getLocalFastQualifiers());
266 }
267 
268 TEST_F(TestTypeSystemClang, TestConvertAccessTypeToAccessSpecifier) {
269   EXPECT_EQ(AS_none,
270             TypeSystemClang::ConvertAccessTypeToAccessSpecifier(eAccessNone));
271   EXPECT_EQ(AS_none, TypeSystemClang::ConvertAccessTypeToAccessSpecifier(
272                          eAccessPackage));
273   EXPECT_EQ(AS_public,
274             TypeSystemClang::ConvertAccessTypeToAccessSpecifier(eAccessPublic));
275   EXPECT_EQ(AS_private, TypeSystemClang::ConvertAccessTypeToAccessSpecifier(
276                             eAccessPrivate));
277   EXPECT_EQ(AS_protected, TypeSystemClang::ConvertAccessTypeToAccessSpecifier(
278                               eAccessProtected));
279 }
280 
281 TEST_F(TestTypeSystemClang, TestUnifyAccessSpecifiers) {
282   // Unifying two of the same type should return the same type
283   EXPECT_EQ(AS_public,
284             TypeSystemClang::UnifyAccessSpecifiers(AS_public, AS_public));
285   EXPECT_EQ(AS_private,
286             TypeSystemClang::UnifyAccessSpecifiers(AS_private, AS_private));
287   EXPECT_EQ(AS_protected,
288             TypeSystemClang::UnifyAccessSpecifiers(AS_protected, AS_protected));
289 
290   // Otherwise the result should be the strictest of the two.
291   EXPECT_EQ(AS_private,
292             TypeSystemClang::UnifyAccessSpecifiers(AS_private, AS_public));
293   EXPECT_EQ(AS_private,
294             TypeSystemClang::UnifyAccessSpecifiers(AS_private, AS_protected));
295   EXPECT_EQ(AS_private,
296             TypeSystemClang::UnifyAccessSpecifiers(AS_public, AS_private));
297   EXPECT_EQ(AS_private,
298             TypeSystemClang::UnifyAccessSpecifiers(AS_protected, AS_private));
299   EXPECT_EQ(AS_protected,
300             TypeSystemClang::UnifyAccessSpecifiers(AS_protected, AS_public));
301   EXPECT_EQ(AS_protected,
302             TypeSystemClang::UnifyAccessSpecifiers(AS_public, AS_protected));
303 
304   // None is stricter than everything (by convention)
305   EXPECT_EQ(AS_none,
306             TypeSystemClang::UnifyAccessSpecifiers(AS_none, AS_public));
307   EXPECT_EQ(AS_none,
308             TypeSystemClang::UnifyAccessSpecifiers(AS_none, AS_protected));
309   EXPECT_EQ(AS_none,
310             TypeSystemClang::UnifyAccessSpecifiers(AS_none, AS_private));
311   EXPECT_EQ(AS_none,
312             TypeSystemClang::UnifyAccessSpecifiers(AS_public, AS_none));
313   EXPECT_EQ(AS_none,
314             TypeSystemClang::UnifyAccessSpecifiers(AS_protected, AS_none));
315   EXPECT_EQ(AS_none,
316             TypeSystemClang::UnifyAccessSpecifiers(AS_private, AS_none));
317 }
318 
319 TEST_F(TestTypeSystemClang, TestRecordHasFields) {
320   CompilerType int_type = m_ast->GetBasicType(eBasicTypeInt);
321 
322   // Test that a record with no fields returns false
323   CompilerType empty_base = m_ast->CreateRecordType(
324       nullptr, lldb::eAccessPublic, "EmptyBase", clang::TTK_Struct,
325       lldb::eLanguageTypeC_plus_plus, nullptr);
326   TypeSystemClang::StartTagDeclarationDefinition(empty_base);
327   TypeSystemClang::CompleteTagDeclarationDefinition(empty_base);
328 
329   RecordDecl *empty_base_decl = TypeSystemClang::GetAsRecordDecl(empty_base);
330   EXPECT_NE(nullptr, empty_base_decl);
331   EXPECT_FALSE(TypeSystemClang::RecordHasFields(empty_base_decl));
332 
333   // Test that a record with direct fields returns true
334   CompilerType non_empty_base = m_ast->CreateRecordType(
335       nullptr, lldb::eAccessPublic, "NonEmptyBase", clang::TTK_Struct,
336       lldb::eLanguageTypeC_plus_plus, nullptr);
337   TypeSystemClang::StartTagDeclarationDefinition(non_empty_base);
338   FieldDecl *non_empty_base_field_decl = m_ast->AddFieldToRecordType(
339       non_empty_base, "MyField", int_type, eAccessPublic, 0);
340   TypeSystemClang::CompleteTagDeclarationDefinition(non_empty_base);
341   RecordDecl *non_empty_base_decl =
342       TypeSystemClang::GetAsRecordDecl(non_empty_base);
343   EXPECT_NE(nullptr, non_empty_base_decl);
344   EXPECT_NE(nullptr, non_empty_base_field_decl);
345   EXPECT_TRUE(TypeSystemClang::RecordHasFields(non_empty_base_decl));
346 
347   std::vector<std::unique_ptr<clang::CXXBaseSpecifier>> bases;
348 
349   // Test that a record with no direct fields, but fields in a base returns true
350   CompilerType empty_derived = m_ast->CreateRecordType(
351       nullptr, lldb::eAccessPublic, "EmptyDerived", clang::TTK_Struct,
352       lldb::eLanguageTypeC_plus_plus, nullptr);
353   TypeSystemClang::StartTagDeclarationDefinition(empty_derived);
354   std::unique_ptr<clang::CXXBaseSpecifier> non_empty_base_spec =
355       m_ast->CreateBaseClassSpecifier(non_empty_base.GetOpaqueQualType(),
356                                       lldb::eAccessPublic, false, false);
357   bases.push_back(std::move(non_empty_base_spec));
358   bool result = m_ast->TransferBaseClasses(empty_derived.GetOpaqueQualType(),
359                                            std::move(bases));
360   TypeSystemClang::CompleteTagDeclarationDefinition(empty_derived);
361   EXPECT_TRUE(result);
362   CXXRecordDecl *empty_derived_non_empty_base_cxx_decl =
363       m_ast->GetAsCXXRecordDecl(empty_derived.GetOpaqueQualType());
364   RecordDecl *empty_derived_non_empty_base_decl =
365       TypeSystemClang::GetAsRecordDecl(empty_derived);
366   EXPECT_EQ(1u, TypeSystemClang::GetNumBaseClasses(
367                     empty_derived_non_empty_base_cxx_decl, false));
368   EXPECT_TRUE(
369       TypeSystemClang::RecordHasFields(empty_derived_non_empty_base_decl));
370 
371   // Test that a record with no direct fields, but fields in a virtual base
372   // returns true
373   CompilerType empty_derived2 = m_ast->CreateRecordType(
374       nullptr, lldb::eAccessPublic, "EmptyDerived2", clang::TTK_Struct,
375       lldb::eLanguageTypeC_plus_plus, nullptr);
376   TypeSystemClang::StartTagDeclarationDefinition(empty_derived2);
377   std::unique_ptr<CXXBaseSpecifier> non_empty_vbase_spec =
378       m_ast->CreateBaseClassSpecifier(non_empty_base.GetOpaqueQualType(),
379                                       lldb::eAccessPublic, true, false);
380   bases.push_back(std::move(non_empty_vbase_spec));
381   result = m_ast->TransferBaseClasses(empty_derived2.GetOpaqueQualType(),
382                                       std::move(bases));
383   TypeSystemClang::CompleteTagDeclarationDefinition(empty_derived2);
384   EXPECT_TRUE(result);
385   CXXRecordDecl *empty_derived_non_empty_vbase_cxx_decl =
386       m_ast->GetAsCXXRecordDecl(empty_derived2.GetOpaqueQualType());
387   RecordDecl *empty_derived_non_empty_vbase_decl =
388       TypeSystemClang::GetAsRecordDecl(empty_derived2);
389   EXPECT_EQ(1u, TypeSystemClang::GetNumBaseClasses(
390                     empty_derived_non_empty_vbase_cxx_decl, false));
391   EXPECT_TRUE(
392       TypeSystemClang::RecordHasFields(empty_derived_non_empty_vbase_decl));
393 }
394 
395 TEST_F(TestTypeSystemClang, TemplateArguments) {
396   TypeSystemClang::TemplateParameterInfos infos;
397   infos.names.push_back("T");
398   infos.args.push_back(TemplateArgument(m_ast->getASTContext().IntTy));
399   infos.names.push_back("I");
400   llvm::APSInt arg(llvm::APInt(8, 47));
401   infos.args.push_back(TemplateArgument(m_ast->getASTContext(), arg,
402                                         m_ast->getASTContext().IntTy));
403 
404   // template<typename T, int I> struct foo;
405   ClassTemplateDecl *decl = m_ast->CreateClassTemplateDecl(
406       m_ast->GetTranslationUnitDecl(), eAccessPublic, "foo", TTK_Struct, infos);
407   ASSERT_NE(decl, nullptr);
408 
409   // foo<int, 47>
410   ClassTemplateSpecializationDecl *spec_decl =
411       m_ast->CreateClassTemplateSpecializationDecl(
412           m_ast->GetTranslationUnitDecl(), decl, TTK_Struct, infos);
413   ASSERT_NE(spec_decl, nullptr);
414   CompilerType type = m_ast->CreateClassTemplateSpecializationType(spec_decl);
415   ASSERT_TRUE(type);
416   m_ast->StartTagDeclarationDefinition(type);
417   m_ast->CompleteTagDeclarationDefinition(type);
418 
419   // typedef foo<int, 47> foo_def;
420   CompilerType typedef_type = m_ast->CreateTypedefType(
421       type, "foo_def", m_ast->CreateDeclContext(m_ast->GetTranslationUnitDecl()));
422 
423   CompilerType auto_type(
424       m_ast.get(),
425       m_ast->getASTContext()
426           .getAutoType(ClangUtil::GetCanonicalQualType(typedef_type),
427                        clang::AutoTypeKeyword::Auto, false)
428           .getAsOpaquePtr());
429 
430   CompilerType int_type(m_ast.get(),
431                         m_ast->getASTContext().IntTy.getAsOpaquePtr());
432   for (CompilerType t : {type, typedef_type, auto_type}) {
433     SCOPED_TRACE(t.GetTypeName().AsCString());
434 
435     EXPECT_EQ(m_ast->GetTemplateArgumentKind(t.GetOpaqueQualType(), 0),
436               eTemplateArgumentKindType);
437     EXPECT_EQ(m_ast->GetTypeTemplateArgument(t.GetOpaqueQualType(), 0),
438               int_type);
439     EXPECT_EQ(llvm::None,
440               m_ast->GetIntegralTemplateArgument(t.GetOpaqueQualType(), 0));
441 
442     EXPECT_EQ(m_ast->GetTemplateArgumentKind(t.GetOpaqueQualType(), 1),
443               eTemplateArgumentKindIntegral);
444     EXPECT_EQ(m_ast->GetTypeTemplateArgument(t.GetOpaqueQualType(), 1),
445               CompilerType());
446     auto result = m_ast->GetIntegralTemplateArgument(t.GetOpaqueQualType(), 1);
447     ASSERT_NE(llvm::None, result);
448     EXPECT_EQ(arg, result->value);
449     EXPECT_EQ(int_type, result->type);
450   }
451 }
452 
453 static QualType makeConstInt(clang::ASTContext &ctxt) {
454   QualType result(ctxt.IntTy);
455   result.addConst();
456   return result;
457 }
458 
459 TEST_F(TestTypeSystemClang, TestGetTypeClassDeclType) {
460   clang::ASTContext &ctxt = m_ast->getASTContext();
461   auto *nullptr_expr = new (ctxt) CXXNullPtrLiteralExpr(ctxt.NullPtrTy, SourceLocation());
462   QualType t = ctxt.getDecltypeType(nullptr_expr, makeConstInt(ctxt));
463   EXPECT_EQ(lldb::eTypeClassBuiltin, m_ast->GetTypeClass(t.getAsOpaquePtr()));
464 }
465 
466 TEST_F(TestTypeSystemClang, TestGetTypeClassTypeOf) {
467   clang::ASTContext &ctxt = m_ast->getASTContext();
468   QualType t = ctxt.getTypeOfType(makeConstInt(ctxt));
469   EXPECT_EQ(lldb::eTypeClassBuiltin, m_ast->GetTypeClass(t.getAsOpaquePtr()));
470 }
471 
472 TEST_F(TestTypeSystemClang, TestGetTypeClassTypeOfExpr) {
473   clang::ASTContext &ctxt = m_ast->getASTContext();
474   auto *nullptr_expr = new (ctxt) CXXNullPtrLiteralExpr(ctxt.NullPtrTy, SourceLocation());
475   QualType t = ctxt.getTypeOfExprType(nullptr_expr);
476   EXPECT_EQ(lldb::eTypeClassBuiltin, m_ast->GetTypeClass(t.getAsOpaquePtr()));
477 }
478 
479 TEST_F(TestTypeSystemClang, TestGetTypeClassNested) {
480   clang::ASTContext &ctxt = m_ast->getASTContext();
481   QualType t_base = ctxt.getTypeOfType(makeConstInt(ctxt));
482   QualType t = ctxt.getTypeOfType(t_base);
483   EXPECT_EQ(lldb::eTypeClassBuiltin, m_ast->GetTypeClass(t.getAsOpaquePtr()));
484 }
485 
486 TEST_F(TestTypeSystemClang, TestFunctionTemplateConstruction) {
487   // Tests creating a function template.
488 
489   CompilerType int_type = m_ast->GetBasicType(lldb::eBasicTypeInt);
490   clang::TranslationUnitDecl *TU = m_ast->GetTranslationUnitDecl();
491 
492   // Prepare the declarations/types we need for the template.
493   CompilerType clang_type =
494       m_ast->CreateFunctionType(int_type, nullptr, 0U, false, 0U);
495   FunctionDecl *func =
496       m_ast->CreateFunctionDeclaration(TU, "foo", clang_type, 0, false);
497   TypeSystemClang::TemplateParameterInfos empty_params;
498 
499   // Create the actual function template.
500   clang::FunctionTemplateDecl *func_template =
501       m_ast->CreateFunctionTemplateDecl(TU, func, "foo", empty_params);
502 
503   EXPECT_EQ(TU, func_template->getDeclContext());
504   EXPECT_EQ("foo", func_template->getName());
505   EXPECT_EQ(clang::AccessSpecifier::AS_none, func_template->getAccess());
506 }
507 
508 TEST_F(TestTypeSystemClang, TestFunctionTemplateInRecordConstruction) {
509   // Tests creating a function template inside a record.
510 
511   CompilerType int_type = m_ast->GetBasicType(lldb::eBasicTypeInt);
512   clang::TranslationUnitDecl *TU = m_ast->GetTranslationUnitDecl();
513 
514   // Create a record we can put the function template int.
515   CompilerType record_type =
516       clang_utils::createRecordWithField(*m_ast, "record", int_type, "field");
517   clang::TagDecl *record = ClangUtil::GetAsTagDecl(record_type);
518 
519   // Prepare the declarations/types we need for the template.
520   CompilerType clang_type =
521       m_ast->CreateFunctionType(int_type, nullptr, 0U, false, 0U);
522   // We create the FunctionDecl for the template in the TU DeclContext because:
523   // 1. FunctionDecls can't be in a Record (only CXXMethodDecls can).
524   // 2. It is mirroring the behavior of DWARFASTParserClang::ParseSubroutine.
525   FunctionDecl *func =
526       m_ast->CreateFunctionDeclaration(TU, "foo", clang_type, 0, false);
527   TypeSystemClang::TemplateParameterInfos empty_params;
528 
529   // Create the actual function template.
530   clang::FunctionTemplateDecl *func_template =
531       m_ast->CreateFunctionTemplateDecl(record, func, "foo", empty_params);
532 
533   EXPECT_EQ(record, func_template->getDeclContext());
534   EXPECT_EQ("foo", func_template->getName());
535   EXPECT_EQ(clang::AccessSpecifier::AS_public, func_template->getAccess());
536 }
537 
538 TEST_F(TestTypeSystemClang, TestDeletingImplicitCopyCstrDueToMoveCStr) {
539   // We need to simulate this behavior in our AST that we construct as we don't
540   // have a Sema instance that can do this for us:
541   // C++11 [class.copy]p7, p18:
542   //  If the class definition declares a move constructor or move assignment
543   //  operator, an implicitly declared copy constructor or copy assignment
544   //  operator is defined as deleted.
545 
546   // Create a record and start defining it.
547   llvm::StringRef class_name = "S";
548   CompilerType t = clang_utils::createRecord(*m_ast, class_name);
549   m_ast->StartTagDeclarationDefinition(t);
550 
551   // Create a move constructor that will delete the implicit copy constructor.
552   CompilerType return_type = m_ast->GetBasicType(lldb::eBasicTypeVoid);
553   CompilerType param_type = t.GetRValueReferenceType();
554   CompilerType function_type =
555       m_ast->CreateFunctionType(return_type, &param_type, /*num_params*/ 1,
556                                 /*variadic=*/false, /*quals*/ 0U);
557   bool is_virtual = false;
558   bool is_static = false;
559   bool is_inline = false;
560   bool is_explicit = true;
561   bool is_attr_used = false;
562   bool is_artificial = false;
563   m_ast->AddMethodToCXXRecordType(
564       t.GetOpaqueQualType(), class_name, nullptr, function_type,
565       lldb::AccessType::eAccessPublic, is_virtual, is_static, is_inline,
566       is_explicit, is_attr_used, is_artificial);
567 
568   // Complete the definition and check the created record.
569   m_ast->CompleteTagDeclarationDefinition(t);
570   auto *record = llvm::cast<CXXRecordDecl>(ClangUtil::GetAsTagDecl(t));
571   // We can't call defaultedCopyConstructorIsDeleted() as this requires that
572   // the Decl passes through Sema which will actually compute this field.
573   // Instead we check that there is no copy constructor declared by the user
574   // which only leaves a non-deleted defaulted copy constructor as an option
575   // that our record will have no simple copy constructor.
576   EXPECT_FALSE(record->hasUserDeclaredCopyConstructor());
577   EXPECT_FALSE(record->hasSimpleCopyConstructor());
578 }
579 
580 TEST_F(TestTypeSystemClang, TestNotDeletingUserCopyCstrDueToMoveCStr) {
581   // Tests that we don't delete the a user-defined copy constructor when
582   // a move constructor is provided.
583   // See also the TestDeletingImplicitCopyCstrDueToMoveCStr test.
584   llvm::StringRef class_name = "S";
585   CompilerType t = clang_utils::createRecord(*m_ast, class_name);
586   m_ast->StartTagDeclarationDefinition(t);
587 
588   CompilerType return_type = m_ast->GetBasicType(lldb::eBasicTypeVoid);
589   bool is_virtual = false;
590   bool is_static = false;
591   bool is_inline = false;
592   bool is_explicit = true;
593   bool is_attr_used = false;
594   bool is_artificial = false;
595   // Create a move constructor.
596   {
597     CompilerType param_type = t.GetRValueReferenceType();
598     CompilerType function_type =
599         m_ast->CreateFunctionType(return_type, &param_type, /*num_params*/ 1,
600                                   /*variadic=*/false, /*quals*/ 0U);
601     m_ast->AddMethodToCXXRecordType(
602         t.GetOpaqueQualType(), class_name, nullptr, function_type,
603         lldb::AccessType::eAccessPublic, is_virtual, is_static, is_inline,
604         is_explicit, is_attr_used, is_artificial);
605   }
606   // Create a copy constructor.
607   {
608     CompilerType param_type = t.GetLValueReferenceType().AddConstModifier();
609     CompilerType function_type =
610         m_ast->CreateFunctionType(return_type, &param_type, /*num_params*/ 1,
611                                   /*variadic=*/false, /*quals*/ 0U);
612     m_ast->AddMethodToCXXRecordType(
613         t.GetOpaqueQualType(), class_name, nullptr, function_type,
614         lldb::AccessType::eAccessPublic, is_virtual, is_static, is_inline,
615         is_explicit, is_attr_used, is_artificial);
616   }
617 
618   // Complete the definition and check the created record.
619   m_ast->CompleteTagDeclarationDefinition(t);
620   auto *record = llvm::cast<CXXRecordDecl>(ClangUtil::GetAsTagDecl(t));
621   EXPECT_TRUE(record->hasUserDeclaredCopyConstructor());
622 }
623