1 //===-- TestTypeSystemClang.cpp -------------------------------------------===//
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
7 //===----------------------------------------------------------------------===//
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"
21 using namespace clang
;
23 using namespace lldb_private
;
25 class TestTypeSystemClang
: public testing::Test
{
27 SubsystemRAII
<FileSystem
, HostInfo
> subsystems
;
29 void SetUp() override
{
31 new TypeSystemClang("test ASTContext", HostInfo::GetTargetTriple()));
34 void TearDown() override
{ m_ast
.reset(); }
37 std::unique_ptr
<TypeSystemClang
> m_ast
;
39 QualType
GetBasicQualType(BasicType type
) const {
40 return ClangUtil::GetQualType(m_ast
->GetBasicTypeFromAST(type
));
43 QualType
GetBasicQualType(const char *name
) const {
44 return ClangUtil::GetQualType(
45 m_ast
->GetBuiltinTypeByName(ConstString(name
)));
49 TEST_F(TestTypeSystemClang
, TestGetBasicTypeFromEnum
) {
50 clang::ASTContext
&context
= m_ast
->getASTContext();
53 context
.hasSameType(GetBasicQualType(eBasicTypeBool
), context
.BoolTy
));
55 context
.hasSameType(GetBasicQualType(eBasicTypeChar
), context
.CharTy
));
56 EXPECT_TRUE(context
.hasSameType(GetBasicQualType(eBasicTypeChar16
),
58 EXPECT_TRUE(context
.hasSameType(GetBasicQualType(eBasicTypeChar32
),
60 EXPECT_TRUE(context
.hasSameType(GetBasicQualType(eBasicTypeDouble
),
62 EXPECT_TRUE(context
.hasSameType(GetBasicQualType(eBasicTypeDoubleComplex
),
63 context
.getComplexType(context
.DoubleTy
)));
65 context
.hasSameType(GetBasicQualType(eBasicTypeFloat
), context
.FloatTy
));
66 EXPECT_TRUE(context
.hasSameType(GetBasicQualType(eBasicTypeFloatComplex
),
67 context
.getComplexType(context
.FloatTy
)));
69 context
.hasSameType(GetBasicQualType(eBasicTypeHalf
), context
.HalfTy
));
71 context
.hasSameType(GetBasicQualType(eBasicTypeInt
), context
.IntTy
));
72 EXPECT_TRUE(context
.hasSameType(GetBasicQualType(eBasicTypeInt128
),
75 context
.hasSameType(GetBasicQualType(eBasicTypeLong
), context
.LongTy
));
76 EXPECT_TRUE(context
.hasSameType(GetBasicQualType(eBasicTypeLongDouble
),
77 context
.LongDoubleTy
));
79 context
.hasSameType(GetBasicQualType(eBasicTypeLongDoubleComplex
),
80 context
.getComplexType(context
.LongDoubleTy
)));
81 EXPECT_TRUE(context
.hasSameType(GetBasicQualType(eBasicTypeLongLong
),
83 EXPECT_TRUE(context
.hasSameType(GetBasicQualType(eBasicTypeNullPtr
),
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()));
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
));
108 context
.hasSameType(GetBasicQualType(eBasicTypeVoid
), context
.VoidTy
));
110 context
.hasSameType(GetBasicQualType(eBasicTypeWChar
), context
.WCharTy
));
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"));
164 void VerifyEncodingAndBitSize(TypeSystemClang
&clang_context
,
165 lldb::Encoding encoding
, unsigned int bit_size
) {
166 clang::ASTContext
&context
= clang_context
.getASTContext();
169 clang_context
.GetBuiltinTypeForEncodingAndBitSize(encoding
, bit_size
);
170 EXPECT_TRUE(type
.IsValid());
172 QualType qtype
= ClangUtil::GetQualType(type
);
173 EXPECT_FALSE(qtype
.isNull());
177 uint64_t actual_size
= context
.getTypeSize(qtype
);
178 EXPECT_EQ(bit_size
, actual_size
);
180 const clang::Type
*type_ptr
= qtype
.getTypePtr();
181 EXPECT_NE(nullptr, type_ptr
);
185 EXPECT_TRUE(type_ptr
->isBuiltinType());
188 EXPECT_TRUE(type_ptr
->isSignedIntegerType());
191 EXPECT_TRUE(type_ptr
->isUnsignedIntegerType());
193 case eEncodingIEEE754
:
194 EXPECT_TRUE(type_ptr
->isFloatingType());
197 FAIL() << "Unexpected encoding";
202 TEST_F(TestTypeSystemClang
, TestBuiltinTypeForEncodingAndBitSize
) {
203 // Make sure we can get types of every possible size in every possible
205 // We can't make any guarantee about which specific type we get, because the
207 // isn't that specific. We only need to make sure the compiler hands us some
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);
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);
222 VerifyEncodingAndBitSize(*m_ast
, eEncodingIEEE754
, 32);
223 VerifyEncodingAndBitSize(*m_ast
, eEncodingIEEE754
, 64);
226 TEST_F(TestTypeSystemClang
, TestDisplayName
) {
227 TypeSystemClang
ast("some name", llvm::Triple());
228 EXPECT_EQ("some name", ast
.getDisplayName());
231 TEST_F(TestTypeSystemClang
, TestDisplayNameEmpty
) {
232 TypeSystemClang
ast("", llvm::Triple());
233 EXPECT_EQ("", ast
.getDisplayName());
236 TEST_F(TestTypeSystemClang
, TestGetEnumIntegerTypeInvalid
) {
237 EXPECT_FALSE(m_ast
->GetEnumerationIntegerType(CompilerType()).IsValid());
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());
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
,
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
));
258 TypeSystemClang
ast("enum_ast", HostInfo::GetTargetTriple());
259 CompilerType basic_compiler_type
= ast
.GetBasicType(basic_type
);
260 EXPECT_TRUE(basic_compiler_type
.IsValid());
262 CompilerType enum_type
= ast
.CreateEnumerationType(
263 "my_enum", ast
.GetTranslationUnitDecl(), OptionalClangModuleID(),
264 Declaration(), basic_compiler_type
, scoped
);
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());
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
);
281 EXPECT_EQ(ed
->getOwningModuleID(), 100u);
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
);
288 EXPECT_EQ(rd
->getOwningModuleID(), 200u);
290 CompilerType class_type
=
291 ast
.CreateObjCClass("objc_class", ast
.GetTranslationUnitDecl(),
292 OptionalClangModuleID(300), false, false);
293 auto *cd
= TypeSystemClang::GetAsObjCInterfaceDecl(class_type
);
295 EXPECT_EQ(cd
->getOwningModuleID(), 300u);
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
));
310 // Default constructed type should fail
311 EXPECT_FALSE(ClangUtil::IsClangType(CompilerType()));
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);
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());
332 TEST_F(TestTypeSystemClang
, TestConvertAccessTypeToAccessSpecifier
) {
334 TypeSystemClang::ConvertAccessTypeToAccessSpecifier(eAccessNone
));
335 EXPECT_EQ(AS_none
, TypeSystemClang::ConvertAccessTypeToAccessSpecifier(
338 TypeSystemClang::ConvertAccessTypeToAccessSpecifier(eAccessPublic
));
339 EXPECT_EQ(AS_private
, TypeSystemClang::ConvertAccessTypeToAccessSpecifier(
341 EXPECT_EQ(AS_protected
, TypeSystemClang::ConvertAccessTypeToAccessSpecifier(
345 TEST_F(TestTypeSystemClang
, TestUnifyAccessSpecifiers
) {
346 // Unifying two of the same type should return the same type
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
));
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
));
368 // None is stricter than everything (by convention)
370 TypeSystemClang::UnifyAccessSpecifiers(AS_none
, AS_public
));
372 TypeSystemClang::UnifyAccessSpecifiers(AS_none
, AS_protected
));
374 TypeSystemClang::UnifyAccessSpecifiers(AS_none
, AS_private
));
376 TypeSystemClang::UnifyAccessSpecifiers(AS_public
, AS_none
));
378 TypeSystemClang::UnifyAccessSpecifiers(AS_protected
, AS_none
));
380 TypeSystemClang::UnifyAccessSpecifiers(AS_private
, AS_none
));
383 TEST_F(TestTypeSystemClang
, TestRecordHasFields
) {
384 CompilerType int_type
= m_ast
->GetBasicType(eBasicTypeInt
);
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
);
393 RecordDecl
*empty_base_decl
= TypeSystemClang::GetAsRecordDecl(empty_base
);
394 EXPECT_NE(nullptr, empty_base_decl
);
395 EXPECT_FALSE(TypeSystemClang::RecordHasFields(empty_base_decl
));
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
));
411 std::vector
<std::unique_ptr
<clang::CXXBaseSpecifier
>> bases
;
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(),
424 TypeSystemClang::CompleteTagDeclarationDefinition(empty_derived
);
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));
433 TypeSystemClang::RecordHasFields(empty_derived_non_empty_base_decl
));
435 // Test that a record with no direct fields, but fields in a virtual base
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(),
447 TypeSystemClang::CompleteTagDeclarationDefinition(empty_derived2
);
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));
456 TypeSystemClang::RecordHasFields(empty_derived_non_empty_vbase_decl
));
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
));
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);
475 ClassTemplateSpecializationDecl
*spec_decl
=
476 m_ast
->CreateClassTemplateSpecializationDecl(
477 m_ast
->GetTranslationUnitDecl(), OptionalClangModuleID(), decl
,
479 ASSERT_NE(spec_decl
, nullptr);
480 CompilerType type
= m_ast
->CreateClassTemplateSpecializationType(spec_decl
);
482 m_ast
->StartTagDeclarationDefinition(type
);
483 m_ast
->CompleteTagDeclarationDefinition(type
);
485 // typedef foo<int, 47> foo_def;
486 CompilerType typedef_type
= type
.CreateTypedef(
487 "foo_def", m_ast
->CreateDeclContext(m_ast
->GetTranslationUnitDecl()), 0);
489 CompilerType
auto_type(
491 m_ast
->getASTContext()
492 .getAutoType(ClangUtil::GetCanonicalQualType(typedef_type
),
493 clang::AutoTypeKeyword::Auto
, false)
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());
501 EXPECT_EQ(m_ast
->GetTemplateArgumentKind(t
.GetOpaqueQualType(), 0),
502 eTemplateArgumentKindType
);
503 EXPECT_EQ(m_ast
->GetTypeTemplateArgument(t
.GetOpaqueQualType(), 0),
505 EXPECT_EQ(llvm::None
,
506 m_ast
->GetIntegralTemplateArgument(t
.GetOpaqueQualType(), 0));
508 EXPECT_EQ(m_ast
->GetTemplateArgumentKind(t
.GetOpaqueQualType(), 1),
509 eTemplateArgumentKindIntegral
);
510 EXPECT_EQ(m_ast
->GetTypeTemplateArgument(t
.GetOpaqueQualType(), 1),
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
);
519 class TestCreateClassTemplateDecl
: public TestTypeSystemClang
{
521 /// The class templates created so far by the Expect* functions below.
522 llvm::DenseSet
<ClassTemplateDecl
*> m_created_templates
;
524 /// Utility function for creating a class template.
526 CreateClassTemplate(const TypeSystemClang::TemplateParameterInfos
&infos
) {
527 ClassTemplateDecl
*decl
= m_ast
->CreateClassTemplateDecl(
528 m_ast
->GetTranslationUnitDecl(), OptionalClangModuleID(), eAccessPublic
,
529 "foo", TTK_Struct
, infos
);
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.
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
);
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
;
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.
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
);
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.)
583 // This describes a class template *instantiation* from which we will infer
584 // the structure of the class template.
585 TypeSystemClang::TemplateParameterInfos infos
;
587 // Test an empty template parameter list: <>
588 ExpectNewTemplate("<>", infos
);
590 // Test that <typename T> with T = int creates a new template.
592 infos
.args
= {TemplateArgument(m_ast
->getASTContext().IntTy
)};
593 ClassTemplateDecl
*single_type_arg
= ExpectNewTemplate("<typename T>", infos
);
595 // Test that changing the parameter name doesn't create a new class template.
597 ExpectReusedTemplate("<typename A> (A = int)", infos
, single_type_arg
);
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
);
603 // Test that <typename A, signed char I> creates a new template with A = int
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
);
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
);
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
);
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
);
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
);
643 TEST_F(TestCreateClassTemplateDecl
, FindExistingTemplatesWithParameterPack
) {
644 // The same as FindExistingTemplates but for templates with parameter packs.
646 TypeSystemClang::TemplateParameterInfos infos
;
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
);
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.
659 std::make_unique
<TypeSystemClang::TemplateParameterInfos
>();
660 ExpectReusedTemplate("<...> (no values in pack)", infos
, type_pack
);
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
);
668 // Change the number of pack values.
669 infos
.packed_args
->args
= {TemplateArgument(m_ast
->getASTContext().IntTy
)};
670 ExpectReusedTemplate("<typename ...> (int)", infos
, type_pack
);
672 // The names of the pack values shouldn't matter.
673 infos
.packed_args
->names
= {"A", "B"};
674 ExpectReusedTemplate("<typename ...> (int)", infos
, type_pack
);
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
);
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
);
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
);
694 // Prependinding a non-pack parameter will create a new template.
696 infos
.args
= {TemplateArgument(m_ast
->getASTContext().IntTy
)};
697 ExpectNewTemplate("<typename T, long...> (T = int, long = 1)", infos
);
700 TEST_F(TestTypeSystemClang
, OnlyPackName
) {
701 TypeSystemClang::TemplateParameterInfos infos
;
702 infos
.pack_name
= "A";
703 EXPECT_FALSE(infos
.IsValid());
706 static QualType
makeConstInt(clang::ASTContext
&ctxt
) {
707 QualType
result(ctxt
.IntTy
);
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()));
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()));
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()));
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()));
739 TEST_F(TestTypeSystemClang
, TestFunctionTemplateConstruction
) {
740 // Tests creating a function template.
742 CompilerType int_type
= m_ast
->GetBasicType(lldb::eBasicTypeInt
);
743 clang::TranslationUnitDecl
*TU
= m_ast
->GetTranslationUnitDecl();
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
,
751 TypeSystemClang::TemplateParameterInfos empty_params
;
753 // Create the actual function template.
754 clang::FunctionTemplateDecl
*func_template
=
755 m_ast
->CreateFunctionTemplateDecl(TU
, OptionalClangModuleID(), func
,
758 EXPECT_EQ(TU
, func_template
->getDeclContext());
759 EXPECT_EQ("foo", func_template
->getName());
760 EXPECT_EQ(clang::AccessSpecifier::AS_none
, func_template
->getAccess());
763 TEST_F(TestTypeSystemClang
, TestFunctionTemplateInRecordConstruction
) {
764 // Tests creating a function template inside a record.
766 CompilerType int_type
= m_ast
->GetBasicType(lldb::eBasicTypeInt
);
767 clang::TranslationUnitDecl
*TU
= m_ast
->GetTranslationUnitDecl();
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
);
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
,
783 TypeSystemClang::TemplateParameterInfos empty_params
;
785 // Create the actual function template.
786 clang::FunctionTemplateDecl
*func_template
=
787 m_ast
->CreateFunctionTemplateDecl(record
, OptionalClangModuleID(), func
,
790 EXPECT_EQ(record
, func_template
->getDeclContext());
791 EXPECT_EQ("foo", func_template
->getName());
792 EXPECT_EQ(clang::AccessSpecifier::AS_public
, func_template
->getAccess());
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.
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
);
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
, ¶m_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
);
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());
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
);
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.
854 CompilerType param_type
= t
.GetRValueReferenceType();
855 CompilerType function_type
=
856 m_ast
->CreateFunctionType(return_type
, ¶m_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
);
863 // Create a copy constructor.
865 CompilerType param_type
= t
.GetLValueReferenceType().AddConstModifier();
866 CompilerType function_type
=
867 m_ast
->CreateFunctionType(return_type
, ¶m_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
);
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());
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());
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
,
903 ASSERT_NE(method
, nullptr);
905 // The interface decl should still have external lexical storage.
906 EXPECT_TRUE(interface
->hasExternalLexicalStorage());
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");
915 TEST_F(TestTypeSystemClang
, GetFullyUnqualifiedType
) {
916 CompilerType bool_
= m_ast
->GetBasicType(eBasicTypeBool
);
917 CompilerType cv_bool
= bool_
.AddConstModifier().AddVolatileModifier();
919 // const volatile bool -> bool
920 EXPECT_EQ(bool_
, cv_bool
.GetFullyUnqualifiedType());
922 // const volatile bool[47] -> bool[47]
923 EXPECT_EQ(bool_
.GetArrayType(47),
924 cv_bool
.GetArrayType(47).GetFullyUnqualifiedType());
926 // const volatile bool[47][42] -> bool[47][42]
928 bool_
.GetArrayType(42).GetArrayType(47),
929 cv_bool
.GetArrayType(42).GetArrayType(47).GetFullyUnqualifiedType());
931 // const volatile bool * -> bool *
932 EXPECT_EQ(bool_
.GetPointerType(),
933 cv_bool
.GetPointerType().GetFullyUnqualifiedType());
935 // const volatile bool *[47] -> bool *[47]
937 bool_
.GetPointerType().GetArrayType(47),
938 cv_bool
.GetPointerType().GetArrayType(47).GetFullyUnqualifiedType());
941 TEST(TestScratchTypeSystemClang
, InferSubASTFromLangOpts
) {
942 LangOptions lang_opts
;
944 ScratchTypeSystemClang::DefaultAST
,
945 ScratchTypeSystemClang::InferIsolatedASTKindFromLangOpts(lang_opts
));
947 lang_opts
.Modules
= true;
949 ScratchTypeSystemClang::IsolatedASTKind::CppModules
,
950 ScratchTypeSystemClang::InferIsolatedASTKindFromLangOpts(lang_opts
));
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);