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 "lldb/lldb-enumerations.h"
17 #include "clang/AST/DeclCXX.h"
18 #include "clang/AST/DeclObjC.h"
19 #include "clang/AST/ExprCXX.h"
20 #include "gtest/gtest.h"
22 using namespace clang
;
24 using namespace lldb_private
;
26 class TestTypeSystemClang
: public testing::Test
{
28 SubsystemRAII
<FileSystem
, HostInfo
> subsystems
;
30 void SetUp() override
{
32 std::make_unique
<clang_utils::TypeSystemClangHolder
>("test ASTContext");
33 m_ast
= m_holder
->GetAST();
36 void TearDown() override
{
43 TypeSystemClang
*m_ast
= nullptr;
44 std::unique_ptr
<clang_utils::TypeSystemClangHolder
> m_holder
;
46 QualType
GetBasicQualType(BasicType type
) const {
47 return ClangUtil::GetQualType(m_ast
->GetBasicTypeFromAST(type
));
50 QualType
GetBasicQualType(const char *name
) const {
51 return ClangUtil::GetQualType(
52 m_ast
->GetBuiltinTypeByName(ConstString(name
)));
56 TEST_F(TestTypeSystemClang
, TestGetBasicTypeFromEnum
) {
57 clang::ASTContext
&context
= m_ast
->getASTContext();
60 context
.hasSameType(GetBasicQualType(eBasicTypeBool
), context
.BoolTy
));
62 context
.hasSameType(GetBasicQualType(eBasicTypeChar
), context
.CharTy
));
63 EXPECT_TRUE(context
.hasSameType(GetBasicQualType(eBasicTypeChar8
),
65 EXPECT_TRUE(context
.hasSameType(GetBasicQualType(eBasicTypeChar16
),
67 EXPECT_TRUE(context
.hasSameType(GetBasicQualType(eBasicTypeChar32
),
69 EXPECT_TRUE(context
.hasSameType(GetBasicQualType(eBasicTypeDouble
),
71 EXPECT_TRUE(context
.hasSameType(GetBasicQualType(eBasicTypeDoubleComplex
),
72 context
.getComplexType(context
.DoubleTy
)));
74 context
.hasSameType(GetBasicQualType(eBasicTypeFloat
), context
.FloatTy
));
75 EXPECT_TRUE(context
.hasSameType(GetBasicQualType(eBasicTypeFloatComplex
),
76 context
.getComplexType(context
.FloatTy
)));
78 context
.hasSameType(GetBasicQualType(eBasicTypeHalf
), context
.HalfTy
));
80 context
.hasSameType(GetBasicQualType(eBasicTypeInt
), context
.IntTy
));
81 EXPECT_TRUE(context
.hasSameType(GetBasicQualType(eBasicTypeInt128
),
84 context
.hasSameType(GetBasicQualType(eBasicTypeLong
), context
.LongTy
));
85 EXPECT_TRUE(context
.hasSameType(GetBasicQualType(eBasicTypeLongDouble
),
86 context
.LongDoubleTy
));
88 context
.hasSameType(GetBasicQualType(eBasicTypeLongDoubleComplex
),
89 context
.getComplexType(context
.LongDoubleTy
)));
90 EXPECT_TRUE(context
.hasSameType(GetBasicQualType(eBasicTypeLongLong
),
92 EXPECT_TRUE(context
.hasSameType(GetBasicQualType(eBasicTypeNullPtr
),
94 EXPECT_TRUE(context
.hasSameType(GetBasicQualType(eBasicTypeObjCClass
),
95 context
.getObjCClassType()));
96 EXPECT_TRUE(context
.hasSameType(GetBasicQualType(eBasicTypeObjCID
),
97 context
.getObjCIdType()));
98 EXPECT_TRUE(context
.hasSameType(GetBasicQualType(eBasicTypeObjCSel
),
99 context
.getObjCSelType()));
101 context
.hasSameType(GetBasicQualType(eBasicTypeShort
), context
.ShortTy
));
102 EXPECT_TRUE(context
.hasSameType(GetBasicQualType(eBasicTypeSignedChar
),
103 context
.SignedCharTy
));
104 EXPECT_TRUE(context
.hasSameType(GetBasicQualType(eBasicTypeUnsignedChar
),
105 context
.UnsignedCharTy
));
106 EXPECT_TRUE(context
.hasSameType(GetBasicQualType(eBasicTypeUnsignedInt
),
107 context
.UnsignedIntTy
));
108 EXPECT_TRUE(context
.hasSameType(GetBasicQualType(eBasicTypeUnsignedInt128
),
109 context
.UnsignedInt128Ty
));
110 EXPECT_TRUE(context
.hasSameType(GetBasicQualType(eBasicTypeUnsignedLong
),
111 context
.UnsignedLongTy
));
112 EXPECT_TRUE(context
.hasSameType(GetBasicQualType(eBasicTypeUnsignedLongLong
),
113 context
.UnsignedLongLongTy
));
114 EXPECT_TRUE(context
.hasSameType(GetBasicQualType(eBasicTypeUnsignedShort
),
115 context
.UnsignedShortTy
));
117 context
.hasSameType(GetBasicQualType(eBasicTypeVoid
), context
.VoidTy
));
119 context
.hasSameType(GetBasicQualType(eBasicTypeWChar
), context
.WCharTy
));
122 TEST_F(TestTypeSystemClang
, TestGetBasicTypeFromName
) {
123 EXPECT_EQ(GetBasicQualType(eBasicTypeChar
), GetBasicQualType("char"));
124 EXPECT_EQ(GetBasicQualType(eBasicTypeSignedChar
),
125 GetBasicQualType("signed char"));
126 EXPECT_EQ(GetBasicQualType(eBasicTypeUnsignedChar
),
127 GetBasicQualType("unsigned char"));
128 EXPECT_EQ(GetBasicQualType(eBasicTypeWChar
), GetBasicQualType("wchar_t"));
129 EXPECT_EQ(GetBasicQualType(eBasicTypeSignedWChar
),
130 GetBasicQualType("signed wchar_t"));
131 EXPECT_EQ(GetBasicQualType(eBasicTypeUnsignedWChar
),
132 GetBasicQualType("unsigned wchar_t"));
133 EXPECT_EQ(GetBasicQualType(eBasicTypeShort
), GetBasicQualType("short"));
134 EXPECT_EQ(GetBasicQualType(eBasicTypeShort
), GetBasicQualType("short int"));
135 EXPECT_EQ(GetBasicQualType(eBasicTypeUnsignedShort
),
136 GetBasicQualType("unsigned short"));
137 EXPECT_EQ(GetBasicQualType(eBasicTypeUnsignedShort
),
138 GetBasicQualType("unsigned short int"));
139 EXPECT_EQ(GetBasicQualType(eBasicTypeInt
), GetBasicQualType("int"));
140 EXPECT_EQ(GetBasicQualType(eBasicTypeInt
), GetBasicQualType("signed int"));
141 EXPECT_EQ(GetBasicQualType(eBasicTypeUnsignedInt
),
142 GetBasicQualType("unsigned int"));
143 EXPECT_EQ(GetBasicQualType(eBasicTypeUnsignedInt
),
144 GetBasicQualType("unsigned"));
145 EXPECT_EQ(GetBasicQualType(eBasicTypeLong
), GetBasicQualType("long"));
146 EXPECT_EQ(GetBasicQualType(eBasicTypeLong
), GetBasicQualType("long int"));
147 EXPECT_EQ(GetBasicQualType(eBasicTypeUnsignedLong
),
148 GetBasicQualType("unsigned long"));
149 EXPECT_EQ(GetBasicQualType(eBasicTypeUnsignedLong
),
150 GetBasicQualType("unsigned long int"));
151 EXPECT_EQ(GetBasicQualType(eBasicTypeLongLong
),
152 GetBasicQualType("long long"));
153 EXPECT_EQ(GetBasicQualType(eBasicTypeLongLong
),
154 GetBasicQualType("long long int"));
155 EXPECT_EQ(GetBasicQualType(eBasicTypeUnsignedLongLong
),
156 GetBasicQualType("unsigned long long"));
157 EXPECT_EQ(GetBasicQualType(eBasicTypeUnsignedLongLong
),
158 GetBasicQualType("unsigned long long int"));
159 EXPECT_EQ(GetBasicQualType(eBasicTypeInt128
), GetBasicQualType("__int128_t"));
160 EXPECT_EQ(GetBasicQualType(eBasicTypeUnsignedInt128
),
161 GetBasicQualType("__uint128_t"));
162 EXPECT_EQ(GetBasicQualType(eBasicTypeVoid
), GetBasicQualType("void"));
163 EXPECT_EQ(GetBasicQualType(eBasicTypeBool
), GetBasicQualType("bool"));
164 EXPECT_EQ(GetBasicQualType(eBasicTypeFloat
), GetBasicQualType("float"));
165 EXPECT_EQ(GetBasicQualType(eBasicTypeDouble
), GetBasicQualType("double"));
166 EXPECT_EQ(GetBasicQualType(eBasicTypeLongDouble
),
167 GetBasicQualType("long double"));
168 EXPECT_EQ(GetBasicQualType(eBasicTypeObjCID
), GetBasicQualType("id"));
169 EXPECT_EQ(GetBasicQualType(eBasicTypeObjCSel
), GetBasicQualType("SEL"));
170 EXPECT_EQ(GetBasicQualType(eBasicTypeNullPtr
), GetBasicQualType("nullptr"));
173 void VerifyEncodingAndBitSize(TypeSystemClang
&clang_context
,
174 lldb::Encoding encoding
, unsigned int bit_size
) {
175 clang::ASTContext
&context
= clang_context
.getASTContext();
178 clang_context
.GetBuiltinTypeForEncodingAndBitSize(encoding
, bit_size
);
179 EXPECT_TRUE(type
.IsValid());
181 QualType qtype
= ClangUtil::GetQualType(type
);
182 EXPECT_FALSE(qtype
.isNull());
186 uint64_t actual_size
= context
.getTypeSize(qtype
);
187 EXPECT_EQ(bit_size
, actual_size
);
189 const clang::Type
*type_ptr
= qtype
.getTypePtr();
190 EXPECT_NE(nullptr, type_ptr
);
194 EXPECT_TRUE(type_ptr
->isBuiltinType());
197 EXPECT_TRUE(type_ptr
->isSignedIntegerType());
200 EXPECT_TRUE(type_ptr
->isUnsignedIntegerType());
202 case eEncodingIEEE754
:
203 EXPECT_TRUE(type_ptr
->isFloatingType());
206 FAIL() << "Unexpected encoding";
211 TEST_F(TestTypeSystemClang
, TestBuiltinTypeForEncodingAndBitSize
) {
212 // Make sure we can get types of every possible size in every possible
214 // We can't make any guarantee about which specific type we get, because the
216 // isn't that specific. We only need to make sure the compiler hands us some
218 // is both a builtin type and matches the requested bit size.
219 VerifyEncodingAndBitSize(*m_ast
, eEncodingSint
, 8);
220 VerifyEncodingAndBitSize(*m_ast
, eEncodingSint
, 16);
221 VerifyEncodingAndBitSize(*m_ast
, eEncodingSint
, 32);
222 VerifyEncodingAndBitSize(*m_ast
, eEncodingSint
, 64);
223 VerifyEncodingAndBitSize(*m_ast
, eEncodingSint
, 128);
225 VerifyEncodingAndBitSize(*m_ast
, eEncodingUint
, 8);
226 VerifyEncodingAndBitSize(*m_ast
, eEncodingUint
, 16);
227 VerifyEncodingAndBitSize(*m_ast
, eEncodingUint
, 32);
228 VerifyEncodingAndBitSize(*m_ast
, eEncodingUint
, 64);
229 VerifyEncodingAndBitSize(*m_ast
, eEncodingUint
, 128);
231 VerifyEncodingAndBitSize(*m_ast
, eEncodingIEEE754
, 32);
232 VerifyEncodingAndBitSize(*m_ast
, eEncodingIEEE754
, 64);
235 TEST_F(TestTypeSystemClang
, TestBuiltinTypeForEmptyTriple
) {
236 // Test that we can access type-info of builtin Clang AST
237 // types without crashing even when the target triple is
240 TypeSystemClang
ast("empty triple AST", llvm::Triple
{});
242 // This test only makes sense if the builtin ASTContext types were
244 ASSERT_TRUE(ast
.getASTContext().VoidPtrTy
.isNull());
246 EXPECT_FALSE(ast
.GetBuiltinTypeByName(ConstString("int")).IsValid());
247 EXPECT_FALSE(ast
.GetBuiltinTypeForDWARFEncodingAndBitSize(
248 "char", dwarf::DW_ATE_signed_char
, 8)
250 EXPECT_FALSE(ast
.GetBuiltinTypeForEncodingAndBitSize(lldb::eEncodingUint
, 8)
252 EXPECT_FALSE(ast
.GetPointerSizedIntType(/*is_signed=*/false));
253 EXPECT_FALSE(ast
.GetIntTypeFromBitSize(8, /*is_signed=*/false));
255 CompilerType record_type
= ast
.CreateRecordType(
256 nullptr, OptionalClangModuleID(), lldb::eAccessPublic
, "Record",
257 llvm::to_underlying(clang::TagTypeKind::Struct
),
258 lldb::eLanguageTypeC_plus_plus
, std::nullopt
);
259 TypeSystemClang::StartTagDeclarationDefinition(record_type
);
260 EXPECT_EQ(ast
.AddFieldToRecordType(record_type
, "field", record_type
,
261 eAccessPublic
, /*bitfield_bit_size=*/8),
263 TypeSystemClang::CompleteTagDeclarationDefinition(record_type
);
266 TEST_F(TestTypeSystemClang
, TestDisplayName
) {
267 TypeSystemClang
ast("some name", llvm::Triple());
268 EXPECT_EQ("some name", ast
.getDisplayName());
271 TEST_F(TestTypeSystemClang
, TestDisplayNameEmpty
) {
272 TypeSystemClang
ast("", llvm::Triple());
273 EXPECT_EQ("", ast
.getDisplayName());
276 TEST_F(TestTypeSystemClang
, TestGetEnumIntegerTypeInvalid
) {
277 EXPECT_FALSE(m_ast
->GetEnumerationIntegerType(CompilerType()).IsValid());
280 TEST_F(TestTypeSystemClang
, TestGetEnumIntegerTypeUnexpectedType
) {
281 CompilerType int_type
= m_ast
->GetBasicType(lldb::eBasicTypeInt
);
282 CompilerType t
= m_ast
->GetEnumerationIntegerType(int_type
);
283 EXPECT_FALSE(t
.IsValid());
286 TEST_F(TestTypeSystemClang
, TestGetEnumIntegerTypeBasicTypes
) {
287 // All possible underlying integer types of enums.
288 const std::vector
<lldb::BasicType
> types_to_test
= {
289 eBasicTypeInt
, eBasicTypeUnsignedInt
, eBasicTypeLong
,
290 eBasicTypeUnsignedLong
, eBasicTypeLongLong
, eBasicTypeUnsignedLongLong
,
293 for (bool scoped
: {true, false}) {
294 SCOPED_TRACE("scoped: " + std::to_string(scoped
));
295 for (lldb::BasicType basic_type
: types_to_test
) {
296 SCOPED_TRACE(std::to_string(basic_type
));
299 std::make_unique
<clang_utils::TypeSystemClangHolder
>("enum_ast");
300 auto &ast
= *holder
->GetAST();
302 CompilerType basic_compiler_type
= ast
.GetBasicType(basic_type
);
303 EXPECT_TRUE(basic_compiler_type
.IsValid());
305 CompilerType enum_type
= ast
.CreateEnumerationType(
306 "my_enum", ast
.GetTranslationUnitDecl(), OptionalClangModuleID(),
307 Declaration(), basic_compiler_type
, scoped
);
309 CompilerType t
= ast
.GetEnumerationIntegerType(enum_type
);
310 // Check that the type we put in at the start is found again.
311 EXPECT_EQ(basic_compiler_type
.GetTypeName(), t
.GetTypeName());
316 TEST_F(TestTypeSystemClang
, TestOwningModule
) {
318 std::make_unique
<clang_utils::TypeSystemClangHolder
>("module_ast");
319 auto &ast
= *holder
->GetAST();
320 CompilerType basic_compiler_type
= ast
.GetBasicType(BasicType::eBasicTypeInt
);
321 CompilerType enum_type
= ast
.CreateEnumerationType(
322 "my_enum", ast
.GetTranslationUnitDecl(), OptionalClangModuleID(100),
323 Declaration(), basic_compiler_type
, false);
324 auto *ed
= TypeSystemClang::GetAsEnumDecl(enum_type
);
326 EXPECT_EQ(ed
->getOwningModuleID(), 100u);
328 CompilerType record_type
= ast
.CreateRecordType(
329 nullptr, OptionalClangModuleID(200), lldb::eAccessPublic
, "FooRecord",
330 llvm::to_underlying(clang::TagTypeKind::Struct
),
331 lldb::eLanguageTypeC_plus_plus
, std::nullopt
);
332 auto *rd
= TypeSystemClang::GetAsRecordDecl(record_type
);
334 EXPECT_EQ(rd
->getOwningModuleID(), 200u);
336 CompilerType class_type
=
337 ast
.CreateObjCClass("objc_class", ast
.GetTranslationUnitDecl(),
338 OptionalClangModuleID(300), false);
339 auto *cd
= TypeSystemClang::GetAsObjCInterfaceDecl(class_type
);
341 EXPECT_EQ(cd
->getOwningModuleID(), 300u);
344 TEST_F(TestTypeSystemClang
, TestIsClangType
) {
345 clang::ASTContext
&context
= m_ast
->getASTContext();
346 lldb::opaque_compiler_type_t bool_ctype
=
347 TypeSystemClang::GetOpaqueCompilerType(&context
, lldb::eBasicTypeBool
);
348 CompilerType
bool_type(m_ast
->weak_from_this(), bool_ctype
);
349 CompilerType record_type
= m_ast
->CreateRecordType(
350 nullptr, OptionalClangModuleID(100), lldb::eAccessPublic
, "FooRecord",
351 llvm::to_underlying(clang::TagTypeKind::Struct
),
352 lldb::eLanguageTypeC_plus_plus
, std::nullopt
);
353 // Clang builtin type and record type should pass
354 EXPECT_TRUE(ClangUtil::IsClangType(bool_type
));
355 EXPECT_TRUE(ClangUtil::IsClangType(record_type
));
357 // Default constructed type should fail
358 EXPECT_FALSE(ClangUtil::IsClangType(CompilerType()));
361 TEST_F(TestTypeSystemClang
, TestRemoveFastQualifiers
) {
362 CompilerType record_type
= m_ast
->CreateRecordType(
363 nullptr, OptionalClangModuleID(), lldb::eAccessPublic
, "FooRecord",
364 llvm::to_underlying(clang::TagTypeKind::Struct
),
365 lldb::eLanguageTypeC_plus_plus
, std::nullopt
);
368 qt
= ClangUtil::GetQualType(record_type
);
369 EXPECT_EQ(0u, qt
.getLocalFastQualifiers());
370 record_type
= record_type
.AddConstModifier();
371 record_type
= record_type
.AddVolatileModifier();
372 record_type
= record_type
.AddRestrictModifier();
373 qt
= ClangUtil::GetQualType(record_type
);
374 EXPECT_NE(0u, qt
.getLocalFastQualifiers());
375 record_type
= ClangUtil::RemoveFastQualifiers(record_type
);
376 qt
= ClangUtil::GetQualType(record_type
);
377 EXPECT_EQ(0u, qt
.getLocalFastQualifiers());
380 TEST_F(TestTypeSystemClang
, TestConvertAccessTypeToAccessSpecifier
) {
382 TypeSystemClang::ConvertAccessTypeToAccessSpecifier(eAccessNone
));
383 EXPECT_EQ(AS_none
, TypeSystemClang::ConvertAccessTypeToAccessSpecifier(
386 TypeSystemClang::ConvertAccessTypeToAccessSpecifier(eAccessPublic
));
387 EXPECT_EQ(AS_private
, TypeSystemClang::ConvertAccessTypeToAccessSpecifier(
389 EXPECT_EQ(AS_protected
, TypeSystemClang::ConvertAccessTypeToAccessSpecifier(
393 TEST_F(TestTypeSystemClang
, TestUnifyAccessSpecifiers
) {
394 // Unifying two of the same type should return the same type
396 TypeSystemClang::UnifyAccessSpecifiers(AS_public
, AS_public
));
397 EXPECT_EQ(AS_private
,
398 TypeSystemClang::UnifyAccessSpecifiers(AS_private
, AS_private
));
399 EXPECT_EQ(AS_protected
,
400 TypeSystemClang::UnifyAccessSpecifiers(AS_protected
, AS_protected
));
402 // Otherwise the result should be the strictest of the two.
403 EXPECT_EQ(AS_private
,
404 TypeSystemClang::UnifyAccessSpecifiers(AS_private
, AS_public
));
405 EXPECT_EQ(AS_private
,
406 TypeSystemClang::UnifyAccessSpecifiers(AS_private
, AS_protected
));
407 EXPECT_EQ(AS_private
,
408 TypeSystemClang::UnifyAccessSpecifiers(AS_public
, AS_private
));
409 EXPECT_EQ(AS_private
,
410 TypeSystemClang::UnifyAccessSpecifiers(AS_protected
, AS_private
));
411 EXPECT_EQ(AS_protected
,
412 TypeSystemClang::UnifyAccessSpecifiers(AS_protected
, AS_public
));
413 EXPECT_EQ(AS_protected
,
414 TypeSystemClang::UnifyAccessSpecifiers(AS_public
, AS_protected
));
416 // None is stricter than everything (by convention)
418 TypeSystemClang::UnifyAccessSpecifiers(AS_none
, AS_public
));
420 TypeSystemClang::UnifyAccessSpecifiers(AS_none
, AS_protected
));
422 TypeSystemClang::UnifyAccessSpecifiers(AS_none
, AS_private
));
424 TypeSystemClang::UnifyAccessSpecifiers(AS_public
, AS_none
));
426 TypeSystemClang::UnifyAccessSpecifiers(AS_protected
, AS_none
));
428 TypeSystemClang::UnifyAccessSpecifiers(AS_private
, AS_none
));
431 TEST_F(TestTypeSystemClang
, TestRecordHasFields
) {
432 CompilerType int_type
= m_ast
->GetBasicType(eBasicTypeInt
);
434 // Test that a record with no fields returns false
435 CompilerType empty_base
= m_ast
->CreateRecordType(
436 nullptr, OptionalClangModuleID(), lldb::eAccessPublic
, "EmptyBase",
437 llvm::to_underlying(clang::TagTypeKind::Struct
),
438 lldb::eLanguageTypeC_plus_plus
, std::nullopt
);
439 TypeSystemClang::StartTagDeclarationDefinition(empty_base
);
440 TypeSystemClang::CompleteTagDeclarationDefinition(empty_base
);
442 RecordDecl
*empty_base_decl
= TypeSystemClang::GetAsRecordDecl(empty_base
);
443 EXPECT_NE(nullptr, empty_base_decl
);
444 EXPECT_FALSE(m_ast
->RecordHasFields(empty_base_decl
));
446 // Test that a record with direct fields returns true
447 CompilerType non_empty_base
= m_ast
->CreateRecordType(
448 nullptr, OptionalClangModuleID(), lldb::eAccessPublic
, "NonEmptyBase",
449 llvm::to_underlying(clang::TagTypeKind::Struct
),
450 lldb::eLanguageTypeC_plus_plus
, std::nullopt
);
451 TypeSystemClang::StartTagDeclarationDefinition(non_empty_base
);
452 FieldDecl
*non_empty_base_field_decl
= m_ast
->AddFieldToRecordType(
453 non_empty_base
, "MyField", int_type
, eAccessPublic
, 0);
454 TypeSystemClang::CompleteTagDeclarationDefinition(non_empty_base
);
455 RecordDecl
*non_empty_base_decl
=
456 TypeSystemClang::GetAsRecordDecl(non_empty_base
);
457 EXPECT_NE(nullptr, non_empty_base_decl
);
458 EXPECT_NE(nullptr, non_empty_base_field_decl
);
459 EXPECT_TRUE(m_ast
->RecordHasFields(non_empty_base_decl
));
461 std::vector
<std::unique_ptr
<clang::CXXBaseSpecifier
>> bases
;
463 // Test that a record with no direct fields, but fields in a base returns true
464 CompilerType empty_derived
= m_ast
->CreateRecordType(
465 nullptr, OptionalClangModuleID(), lldb::eAccessPublic
, "EmptyDerived",
466 llvm::to_underlying(clang::TagTypeKind::Struct
),
467 lldb::eLanguageTypeC_plus_plus
, std::nullopt
);
468 TypeSystemClang::StartTagDeclarationDefinition(empty_derived
);
469 std::unique_ptr
<clang::CXXBaseSpecifier
> non_empty_base_spec
=
470 m_ast
->CreateBaseClassSpecifier(non_empty_base
.GetOpaqueQualType(),
471 lldb::eAccessPublic
, false, false);
472 bases
.push_back(std::move(non_empty_base_spec
));
473 bool result
= m_ast
->TransferBaseClasses(empty_derived
.GetOpaqueQualType(),
475 TypeSystemClang::CompleteTagDeclarationDefinition(empty_derived
);
477 CXXRecordDecl
*empty_derived_non_empty_base_cxx_decl
=
478 m_ast
->GetAsCXXRecordDecl(empty_derived
.GetOpaqueQualType());
479 RecordDecl
*empty_derived_non_empty_base_decl
=
480 TypeSystemClang::GetAsRecordDecl(empty_derived
);
481 EXPECT_EQ(1u, m_ast
->GetNumBaseClasses(
482 empty_derived_non_empty_base_cxx_decl
, false));
483 EXPECT_TRUE(m_ast
->RecordHasFields(empty_derived_non_empty_base_decl
));
485 // Test that a record with no direct fields, but fields in a virtual base
487 CompilerType empty_derived2
= m_ast
->CreateRecordType(
488 nullptr, OptionalClangModuleID(), lldb::eAccessPublic
, "EmptyDerived2",
489 llvm::to_underlying(clang::TagTypeKind::Struct
),
490 lldb::eLanguageTypeC_plus_plus
, std::nullopt
);
491 TypeSystemClang::StartTagDeclarationDefinition(empty_derived2
);
492 std::unique_ptr
<CXXBaseSpecifier
> non_empty_vbase_spec
=
493 m_ast
->CreateBaseClassSpecifier(non_empty_base
.GetOpaqueQualType(),
494 lldb::eAccessPublic
, true, false);
495 bases
.push_back(std::move(non_empty_vbase_spec
));
496 result
= m_ast
->TransferBaseClasses(empty_derived2
.GetOpaqueQualType(),
498 TypeSystemClang::CompleteTagDeclarationDefinition(empty_derived2
);
500 CXXRecordDecl
*empty_derived_non_empty_vbase_cxx_decl
=
501 m_ast
->GetAsCXXRecordDecl(empty_derived2
.GetOpaqueQualType());
502 RecordDecl
*empty_derived_non_empty_vbase_decl
=
503 TypeSystemClang::GetAsRecordDecl(empty_derived2
);
504 EXPECT_EQ(1u, m_ast
->GetNumBaseClasses(
505 empty_derived_non_empty_vbase_cxx_decl
, false));
507 m_ast
->RecordHasFields(empty_derived_non_empty_vbase_decl
));
510 TEST_F(TestTypeSystemClang
, TemplateArguments
) {
511 TypeSystemClang::TemplateParameterInfos infos
;
512 infos
.InsertArg("T", TemplateArgument(m_ast
->getASTContext().IntTy
));
514 llvm::APSInt
arg(llvm::APInt(8, 47));
515 infos
.InsertArg("I", TemplateArgument(m_ast
->getASTContext(), arg
,
516 m_ast
->getASTContext().IntTy
));
518 // template<typename T, int I> struct foo;
519 ClassTemplateDecl
*decl
= m_ast
->CreateClassTemplateDecl(
520 m_ast
->GetTranslationUnitDecl(), OptionalClangModuleID(), eAccessPublic
,
521 "foo", llvm::to_underlying(clang::TagTypeKind::Struct
), infos
);
522 ASSERT_NE(decl
, nullptr);
525 ClassTemplateSpecializationDecl
*spec_decl
=
526 m_ast
->CreateClassTemplateSpecializationDecl(
527 m_ast
->GetTranslationUnitDecl(), OptionalClangModuleID(), decl
,
528 llvm::to_underlying(clang::TagTypeKind::Struct
), infos
);
529 ASSERT_NE(spec_decl
, nullptr);
530 CompilerType type
= m_ast
->CreateClassTemplateSpecializationType(spec_decl
);
532 m_ast
->StartTagDeclarationDefinition(type
);
533 m_ast
->CompleteTagDeclarationDefinition(type
);
535 // typedef foo<int, 47> foo_def;
536 CompilerType typedef_type
= type
.CreateTypedef(
537 "foo_def", m_ast
->CreateDeclContext(m_ast
->GetTranslationUnitDecl()), 0);
539 CompilerType
auto_type(
540 m_ast
->weak_from_this(),
541 m_ast
->getASTContext()
542 .getAutoType(ClangUtil::GetCanonicalQualType(typedef_type
),
543 clang::AutoTypeKeyword::Auto
, false)
546 CompilerType
int_type(m_ast
->weak_from_this(),
547 m_ast
->getASTContext().IntTy
.getAsOpaquePtr());
548 for (CompilerType t
: {type
, typedef_type
, auto_type
}) {
549 SCOPED_TRACE(t
.GetTypeName().AsCString());
551 const bool expand_pack
= false;
553 m_ast
->GetTemplateArgumentKind(t
.GetOpaqueQualType(), 0, expand_pack
),
554 eTemplateArgumentKindType
);
556 m_ast
->GetTypeTemplateArgument(t
.GetOpaqueQualType(), 0, expand_pack
),
558 EXPECT_EQ(std::nullopt
, m_ast
->GetIntegralTemplateArgument(
559 t
.GetOpaqueQualType(), 0, expand_pack
));
562 m_ast
->GetTemplateArgumentKind(t
.GetOpaqueQualType(), 1, expand_pack
),
563 eTemplateArgumentKindIntegral
);
565 m_ast
->GetTypeTemplateArgument(t
.GetOpaqueQualType(), 1, expand_pack
),
567 auto result
= m_ast
->GetIntegralTemplateArgument(t
.GetOpaqueQualType(), 1,
569 ASSERT_NE(std::nullopt
, result
);
570 EXPECT_EQ(arg
, result
->value
);
571 EXPECT_EQ(int_type
, result
->type
);
575 class TestCreateClassTemplateDecl
: public TestTypeSystemClang
{
577 /// The class templates created so far by the Expect* functions below.
578 llvm::DenseSet
<ClassTemplateDecl
*> m_created_templates
;
580 /// Utility function for creating a class template.
582 CreateClassTemplate(const TypeSystemClang::TemplateParameterInfos
&infos
) {
583 ClassTemplateDecl
*decl
= m_ast
->CreateClassTemplateDecl(
584 m_ast
->GetTranslationUnitDecl(), OptionalClangModuleID(), eAccessPublic
,
585 "foo", llvm::to_underlying(clang::TagTypeKind::Struct
), infos
);
589 /// Creates a new class template with the given template parameters.
590 /// Asserts that a new ClassTemplateDecl is created.
591 /// \param description The gtest scope string that should describe the input.
592 /// \param infos The template parameters that the class template should have.
593 /// \returns The created ClassTemplateDecl.
595 ExpectNewTemplate(std::string description
,
596 const TypeSystemClang::TemplateParameterInfos
&infos
) {
597 SCOPED_TRACE(description
);
598 ClassTemplateDecl
*first_template
= CreateClassTemplate(infos
);
599 // A new template should have been created.
600 EXPECT_FALSE(m_created_templates
.contains(first_template
))
601 << "Didn't create new class template but reused this existing decl:\n"
602 << ClangUtil::DumpDecl(first_template
);
603 m_created_templates
.insert(first_template
);
605 // Creating a new template with the same arguments should always return
606 // the template created above.
607 ClassTemplateDecl
*second_template
= CreateClassTemplate(infos
);
608 EXPECT_EQ(first_template
, second_template
)
609 << "Second attempt to create class template didn't reuse first decl:\n"
610 << ClangUtil::DumpDecl(first_template
) << "\nInstead created/reused:\n"
611 << ClangUtil::DumpDecl(second_template
);
612 return first_template
;
615 /// Tries to create a new class template but asserts that an existing class
616 /// template in the current AST is reused (in contract so a new class
617 /// template being created).
618 /// \param description The gtest scope string that should describe the input.
619 /// \param infos The template parameters that the class template should have.
621 ExpectReusedTemplate(std::string description
,
622 const TypeSystemClang::TemplateParameterInfos
&infos
,
623 ClassTemplateDecl
*expected
) {
624 SCOPED_TRACE(description
);
625 ClassTemplateDecl
*td
= CreateClassTemplate(infos
);
626 EXPECT_EQ(td
, expected
)
627 << "Created/reused class template is:\n"
628 << ClangUtil::DumpDecl(td
) << "\nExpected to reuse:\n"
629 << ClangUtil::DumpDecl(expected
);
633 TEST_F(TestCreateClassTemplateDecl
, FindExistingTemplates
) {
634 // This tests the logic in TypeSystemClang::CreateClassTemplateDecl that
635 // decides whether an existing ClassTemplateDecl in the AST can be reused.
636 // The behaviour should follow the C++ rules for redeclaring templates
637 // (e.g., parameter names can be changed/omitted.)
639 // Test an empty template parameter list: <>
640 ExpectNewTemplate("<>", {{}, {}});
642 clang::TemplateArgument
intArg(m_ast
->getASTContext().IntTy
);
643 clang::TemplateArgument
int47Arg(m_ast
->getASTContext(),
644 llvm::APSInt(llvm::APInt(32, 47)),
645 m_ast
->getASTContext().IntTy
);
646 clang::TemplateArgument
floatArg(m_ast
->getASTContext().FloatTy
);
647 clang::TemplateArgument
char47Arg(m_ast
->getASTContext(),
648 llvm::APSInt(llvm::APInt(8, 47)),
649 m_ast
->getASTContext().SignedCharTy
);
651 clang::TemplateArgument
char123Arg(m_ast
->getASTContext(),
652 llvm::APSInt(llvm::APInt(8, 123)),
653 m_ast
->getASTContext().SignedCharTy
);
655 // Test that <typename T> with T = int creates a new template.
656 ClassTemplateDecl
*single_type_arg
=
657 ExpectNewTemplate("<typename T>", {{"T"}, {intArg
}});
659 // Test that changing the parameter name doesn't create a new class template.
660 ExpectReusedTemplate("<typename A> (A = int)", {{"A"}, {intArg
}},
663 // Test that changing the used type doesn't create a new class template.
664 ExpectReusedTemplate("<typename A> (A = float)", {{"A"}, {floatArg
}},
667 // Test that <typename A, signed char I> creates a new template with A = int
669 ClassTemplateDecl
*type_and_char_value
=
670 ExpectNewTemplate("<typename A, signed char I> (I = 47)",
671 {{"A", "I"}, {floatArg
, char47Arg
}});
673 // Change the value of the I parameter to 123. The previously created
674 // class template should still be reused.
675 ExpectReusedTemplate("<typename A, signed char I> (I = 123)",
676 {{"A", "I"}, {floatArg
, char123Arg
}},
677 type_and_char_value
);
679 // Change the type of the I parameter to int so we have <typename A, int I>.
680 // The class template from above can't be reused.
681 ExpectNewTemplate("<typename A, int I> (I = 123)",
682 {{"A", "I"}, {floatArg
, int47Arg
}});
684 // Test a second type parameter will also cause a new template to be created.
685 // We now have <typename A, int I, typename B>.
686 ClassTemplateDecl
*type_and_char_value_and_type
=
687 ExpectNewTemplate("<typename A, int I, typename B>",
688 {{"A", "I", "B"}, {floatArg
, int47Arg
, intArg
}});
690 // Remove all the names from the parameters which shouldn't influence the
691 // way the templates get merged.
692 ExpectReusedTemplate("<typename, int, typename>",
693 {{"", "", ""}, {floatArg
, int47Arg
, intArg
}},
694 type_and_char_value_and_type
);
697 TEST_F(TestCreateClassTemplateDecl
, FindExistingTemplatesWithParameterPack
) {
698 // The same as FindExistingTemplates but for templates with parameter packs.
699 TypeSystemClang::TemplateParameterInfos infos
;
700 clang::TemplateArgument
intArg(m_ast
->getASTContext().IntTy
);
701 clang::TemplateArgument
int1Arg(m_ast
->getASTContext(),
702 llvm::APSInt(llvm::APInt(32, 1)),
703 m_ast
->getASTContext().IntTy
);
704 clang::TemplateArgument
int123Arg(m_ast
->getASTContext(),
705 llvm::APSInt(llvm::APInt(32, 123)),
706 m_ast
->getASTContext().IntTy
);
707 clang::TemplateArgument
longArg(m_ast
->getASTContext().LongTy
);
708 clang::TemplateArgument
long1Arg(m_ast
->getASTContext(),
709 llvm::APSInt(llvm::APInt(64, 1)),
710 m_ast
->getASTContext().LongTy
);
712 infos
.SetParameterPack(
713 std::make_unique
<TypeSystemClang::TemplateParameterInfos
>(
714 llvm::SmallVector
<const char *>{"", ""},
715 llvm::SmallVector
<TemplateArgument
>{intArg
, intArg
}));
717 ClassTemplateDecl
*type_pack
=
718 ExpectNewTemplate("<typename ...> (int, int)", infos
);
720 // Special case: An instantiation for a parameter pack with no values fits
721 // to whatever class template we find. There isn't enough information to
722 // do an actual comparison here.
723 infos
.SetParameterPack(
724 std::make_unique
<TypeSystemClang::TemplateParameterInfos
>());
725 ExpectReusedTemplate("<...> (no values in pack)", infos
, type_pack
);
727 // Change the type content of pack type values.
728 infos
.SetParameterPack(
729 std::make_unique
<TypeSystemClang::TemplateParameterInfos
>(
730 llvm::SmallVector
<const char *>{"", ""},
731 llvm::SmallVector
<TemplateArgument
>{intArg
, longArg
}));
732 ExpectReusedTemplate("<typename ...> (int, long)", infos
, type_pack
);
734 // Change the number of pack values.
735 infos
.SetParameterPack(
736 std::make_unique
<TypeSystemClang::TemplateParameterInfos
>(
737 llvm::SmallVector
<const char *>{""},
738 llvm::SmallVector
<TemplateArgument
>{intArg
}));
739 ExpectReusedTemplate("<typename ...> (int)", infos
, type_pack
);
741 // The names of the pack values shouldn't matter.
742 infos
.SetParameterPack(
743 std::make_unique
<TypeSystemClang::TemplateParameterInfos
>(
744 llvm::SmallVector
<const char *>{"A"},
745 llvm::SmallVector
<TemplateArgument
>{intArg
}));
746 ExpectReusedTemplate("<typename ...> (int)", infos
, type_pack
);
748 // Changing the kind of template argument will create a new template.
749 infos
.SetParameterPack(
750 std::make_unique
<TypeSystemClang::TemplateParameterInfos
>(
751 llvm::SmallVector
<const char *>{"A"},
752 llvm::SmallVector
<TemplateArgument
>{int1Arg
}));
753 ClassTemplateDecl
*int_pack
= ExpectNewTemplate("<int ...> (int = 1)", infos
);
755 // Changing the value of integral parameters will not create a new template.
756 infos
.SetParameterPack(
757 std::make_unique
<TypeSystemClang::TemplateParameterInfos
>(
758 llvm::SmallVector
<const char *>{"A"},
759 llvm::SmallVector
<TemplateArgument
>{int123Arg
}));
760 ExpectReusedTemplate("<int ...> (int = 123)", infos
, int_pack
);
762 // Changing the integral type will create a new template.
763 infos
.SetParameterPack(
764 std::make_unique
<TypeSystemClang::TemplateParameterInfos
>(
765 llvm::SmallVector
<const char *>{"A"},
766 llvm::SmallVector
<TemplateArgument
>{long1Arg
}));
767 ExpectNewTemplate("<long ...> (long = 1)", infos
);
769 // Prependinding a non-pack parameter will create a new template.
770 infos
.InsertArg("T", intArg
);
771 ExpectNewTemplate("<typename T, long...> (T = int, long = 1)", infos
);
774 TEST_F(TestTypeSystemClang
, OnlyPackName
) {
775 TypeSystemClang::TemplateParameterInfos infos
;
776 infos
.SetPackName("A");
777 EXPECT_FALSE(infos
.IsValid());
780 static QualType
makeConstInt(clang::ASTContext
&ctxt
) {
781 QualType
result(ctxt
.IntTy
);
786 TEST_F(TestTypeSystemClang
, TestGetTypeClassDeclType
) {
787 clang::ASTContext
&ctxt
= m_ast
->getASTContext();
788 auto *nullptr_expr
= new (ctxt
) CXXNullPtrLiteralExpr(ctxt
.NullPtrTy
, SourceLocation());
789 QualType t
= ctxt
.getDecltypeType(nullptr_expr
, makeConstInt(ctxt
));
790 EXPECT_EQ(lldb::eTypeClassBuiltin
, m_ast
->GetTypeClass(t
.getAsOpaquePtr()));
793 TEST_F(TestTypeSystemClang
, TestGetTypeClassTypeOf
) {
794 clang::ASTContext
&ctxt
= m_ast
->getASTContext();
795 QualType t
= ctxt
.getTypeOfType(makeConstInt(ctxt
), TypeOfKind::Qualified
);
796 EXPECT_EQ(lldb::eTypeClassBuiltin
, m_ast
->GetTypeClass(t
.getAsOpaquePtr()));
799 TEST_F(TestTypeSystemClang
, TestGetTypeClassTypeOfExpr
) {
800 clang::ASTContext
&ctxt
= m_ast
->getASTContext();
801 auto *nullptr_expr
= new (ctxt
) CXXNullPtrLiteralExpr(ctxt
.NullPtrTy
, SourceLocation());
802 QualType t
= ctxt
.getTypeOfExprType(nullptr_expr
, TypeOfKind::Qualified
);
803 EXPECT_EQ(lldb::eTypeClassBuiltin
, m_ast
->GetTypeClass(t
.getAsOpaquePtr()));
806 TEST_F(TestTypeSystemClang
, TestGetTypeClassNested
) {
807 clang::ASTContext
&ctxt
= m_ast
->getASTContext();
809 ctxt
.getTypeOfType(makeConstInt(ctxt
), TypeOfKind::Qualified
);
810 QualType t
= ctxt
.getTypeOfType(t_base
, TypeOfKind::Qualified
);
811 EXPECT_EQ(lldb::eTypeClassBuiltin
, m_ast
->GetTypeClass(t
.getAsOpaquePtr()));
814 TEST_F(TestTypeSystemClang
, TestFunctionTemplateConstruction
) {
815 // Tests creating a function template.
817 CompilerType int_type
= m_ast
->GetBasicType(lldb::eBasicTypeInt
);
818 clang::TranslationUnitDecl
*TU
= m_ast
->GetTranslationUnitDecl();
820 // Prepare the declarations/types we need for the template.
821 CompilerType clang_type
=
822 m_ast
->CreateFunctionType(int_type
, nullptr, 0U, false, 0U);
823 FunctionDecl
*func
= m_ast
->CreateFunctionDeclaration(
824 TU
, OptionalClangModuleID(), "foo", clang_type
, StorageClass::SC_None
,
826 TypeSystemClang::TemplateParameterInfos empty_params
;
828 // Create the actual function template.
829 clang::FunctionTemplateDecl
*func_template
=
830 m_ast
->CreateFunctionTemplateDecl(TU
, OptionalClangModuleID(), func
,
833 EXPECT_EQ(TU
, func_template
->getDeclContext());
834 EXPECT_EQ("foo", func_template
->getName());
835 EXPECT_EQ(clang::AccessSpecifier::AS_none
, func_template
->getAccess());
838 TEST_F(TestTypeSystemClang
, TestFunctionTemplateInRecordConstruction
) {
839 // Tests creating a function template inside a record.
841 CompilerType int_type
= m_ast
->GetBasicType(lldb::eBasicTypeInt
);
842 clang::TranslationUnitDecl
*TU
= m_ast
->GetTranslationUnitDecl();
844 // Create a record we can put the function template int.
845 CompilerType record_type
=
846 clang_utils::createRecordWithField(*m_ast
, "record", int_type
, "field");
847 clang::TagDecl
*record
= ClangUtil::GetAsTagDecl(record_type
);
849 // Prepare the declarations/types we need for the template.
850 CompilerType clang_type
=
851 m_ast
->CreateFunctionType(int_type
, nullptr, 0U, false, 0U);
852 // We create the FunctionDecl for the template in the TU DeclContext because:
853 // 1. FunctionDecls can't be in a Record (only CXXMethodDecls can).
854 // 2. It is mirroring the behavior of DWARFASTParserClang::ParseSubroutine.
855 FunctionDecl
*func
= m_ast
->CreateFunctionDeclaration(
856 TU
, OptionalClangModuleID(), "foo", clang_type
, StorageClass::SC_None
,
858 TypeSystemClang::TemplateParameterInfos empty_params
;
860 // Create the actual function template.
861 clang::FunctionTemplateDecl
*func_template
=
862 m_ast
->CreateFunctionTemplateDecl(record
, OptionalClangModuleID(), func
,
865 EXPECT_EQ(record
, func_template
->getDeclContext());
866 EXPECT_EQ("foo", func_template
->getName());
867 EXPECT_EQ(clang::AccessSpecifier::AS_public
, func_template
->getAccess());
870 TEST_F(TestTypeSystemClang
, TestDeletingImplicitCopyCstrDueToMoveCStr
) {
871 // We need to simulate this behavior in our AST that we construct as we don't
872 // have a Sema instance that can do this for us:
873 // C++11 [class.copy]p7, p18:
874 // If the class definition declares a move constructor or move assignment
875 // operator, an implicitly declared copy constructor or copy assignment
876 // operator is defined as deleted.
878 // Create a record and start defining it.
879 llvm::StringRef class_name
= "S";
880 CompilerType t
= clang_utils::createRecord(*m_ast
, class_name
);
881 m_ast
->StartTagDeclarationDefinition(t
);
883 // Create a move constructor that will delete the implicit copy constructor.
884 CompilerType return_type
= m_ast
->GetBasicType(lldb::eBasicTypeVoid
);
885 CompilerType param_type
= t
.GetRValueReferenceType();
886 CompilerType function_type
=
887 m_ast
->CreateFunctionType(return_type
, ¶m_type
, /*num_params*/ 1,
888 /*variadic=*/false, /*quals*/ 0U);
889 bool is_virtual
= false;
890 bool is_static
= false;
891 bool is_inline
= false;
892 bool is_explicit
= true;
893 bool is_attr_used
= false;
894 bool is_artificial
= false;
895 m_ast
->AddMethodToCXXRecordType(
896 t
.GetOpaqueQualType(), class_name
, nullptr, function_type
,
897 lldb::AccessType::eAccessPublic
, is_virtual
, is_static
, is_inline
,
898 is_explicit
, is_attr_used
, is_artificial
);
900 // Complete the definition and check the created record.
901 m_ast
->CompleteTagDeclarationDefinition(t
);
902 auto *record
= llvm::cast
<CXXRecordDecl
>(ClangUtil::GetAsTagDecl(t
));
903 // We can't call defaultedCopyConstructorIsDeleted() as this requires that
904 // the Decl passes through Sema which will actually compute this field.
905 // Instead we check that there is no copy constructor declared by the user
906 // which only leaves a non-deleted defaulted copy constructor as an option
907 // that our record will have no simple copy constructor.
908 EXPECT_FALSE(record
->hasUserDeclaredCopyConstructor());
909 EXPECT_FALSE(record
->hasSimpleCopyConstructor());
912 TEST_F(TestTypeSystemClang
, TestNotDeletingUserCopyCstrDueToMoveCStr
) {
913 // Tests that we don't delete the a user-defined copy constructor when
914 // a move constructor is provided.
915 // See also the TestDeletingImplicitCopyCstrDueToMoveCStr test.
916 llvm::StringRef class_name
= "S";
917 CompilerType t
= clang_utils::createRecord(*m_ast
, class_name
);
918 m_ast
->StartTagDeclarationDefinition(t
);
920 CompilerType return_type
= m_ast
->GetBasicType(lldb::eBasicTypeVoid
);
921 bool is_virtual
= false;
922 bool is_static
= false;
923 bool is_inline
= false;
924 bool is_explicit
= true;
925 bool is_attr_used
= false;
926 bool is_artificial
= false;
927 // Create a move constructor.
929 CompilerType param_type
= t
.GetRValueReferenceType();
930 CompilerType function_type
=
931 m_ast
->CreateFunctionType(return_type
, ¶m_type
, /*num_params*/ 1,
932 /*variadic=*/false, /*quals*/ 0U);
933 m_ast
->AddMethodToCXXRecordType(
934 t
.GetOpaqueQualType(), class_name
, nullptr, function_type
,
935 lldb::AccessType::eAccessPublic
, is_virtual
, is_static
, is_inline
,
936 is_explicit
, is_attr_used
, is_artificial
);
938 // Create a copy constructor.
940 CompilerType param_type
= t
.GetLValueReferenceType().AddConstModifier();
941 CompilerType function_type
=
942 m_ast
->CreateFunctionType(return_type
, ¶m_type
, /*num_params*/ 1,
943 /*variadic=*/false, /*quals*/ 0U);
944 m_ast
->AddMethodToCXXRecordType(
945 t
.GetOpaqueQualType(), class_name
, nullptr, function_type
,
946 lldb::AccessType::eAccessPublic
, is_virtual
, is_static
, is_inline
,
947 is_explicit
, is_attr_used
, is_artificial
);
950 // Complete the definition and check the created record.
951 m_ast
->CompleteTagDeclarationDefinition(t
);
952 auto *record
= llvm::cast
<CXXRecordDecl
>(ClangUtil::GetAsTagDecl(t
));
953 EXPECT_TRUE(record
->hasUserDeclaredCopyConstructor());
956 TEST_F(TestTypeSystemClang
, AddMethodToObjCObjectType
) {
957 // Create an interface decl and mark it as having external storage.
958 CompilerType c
= m_ast
->CreateObjCClass("A", m_ast
->GetTranslationUnitDecl(),
959 OptionalClangModuleID(),
960 /*IsInternal*/ false);
961 ObjCInterfaceDecl
*interface
= m_ast
->GetAsObjCInterfaceDecl(c
);
962 m_ast
->SetHasExternalStorage(c
.GetOpaqueQualType(), true);
963 EXPECT_TRUE(interface
->hasExternalLexicalStorage());
965 // Add a method to the interface.
966 std::vector
<CompilerType
> args
;
967 CompilerType func_type
=
968 m_ast
->CreateFunctionType(m_ast
->GetBasicType(lldb::eBasicTypeInt
),
969 args
.data(), args
.size(), /*variadic*/ false,
970 /*quals*/ 0, clang::CallingConv::CC_C
);
971 bool variadic
= false;
972 bool artificial
= false;
973 bool objc_direct
= false;
974 clang::ObjCMethodDecl
*method
= TypeSystemClang::AddMethodToObjCObjectType(
975 c
, "-[A foo]", func_type
, artificial
, variadic
, objc_direct
);
976 ASSERT_NE(method
, nullptr);
978 // The interface decl should still have external lexical storage.
979 EXPECT_TRUE(interface
->hasExternalLexicalStorage());
981 // Test some properties of the created ObjCMethodDecl.
982 EXPECT_FALSE(method
->isVariadic());
983 EXPECT_TRUE(method
->isImplicit());
984 EXPECT_FALSE(method
->isDirectMethod());
985 EXPECT_EQ(method
->getDeclName().getObjCSelector().getAsString(), "foo");
988 TEST_F(TestTypeSystemClang
, GetFullyUnqualifiedType
) {
989 CompilerType bool_
= m_ast
->GetBasicType(eBasicTypeBool
);
990 CompilerType cv_bool
= bool_
.AddConstModifier().AddVolatileModifier();
992 // const volatile bool -> bool
993 EXPECT_EQ(bool_
, cv_bool
.GetFullyUnqualifiedType());
995 // const volatile bool[47] -> bool[47]
996 EXPECT_EQ(bool_
.GetArrayType(47),
997 cv_bool
.GetArrayType(47).GetFullyUnqualifiedType());
999 // const volatile bool[47][42] -> bool[47][42]
1001 bool_
.GetArrayType(42).GetArrayType(47),
1002 cv_bool
.GetArrayType(42).GetArrayType(47).GetFullyUnqualifiedType());
1004 // const volatile bool * -> bool *
1005 EXPECT_EQ(bool_
.GetPointerType(),
1006 cv_bool
.GetPointerType().GetFullyUnqualifiedType());
1008 // const volatile bool *[47] -> bool *[47]
1010 bool_
.GetPointerType().GetArrayType(47),
1011 cv_bool
.GetPointerType().GetArrayType(47).GetFullyUnqualifiedType());
1014 TEST(TestScratchTypeSystemClang
, InferSubASTFromLangOpts
) {
1015 LangOptions lang_opts
;
1017 ScratchTypeSystemClang::DefaultAST
,
1018 ScratchTypeSystemClang::InferIsolatedASTKindFromLangOpts(lang_opts
));
1020 lang_opts
.Modules
= true;
1022 ScratchTypeSystemClang::IsolatedASTKind::CppModules
,
1023 ScratchTypeSystemClang::InferIsolatedASTKindFromLangOpts(lang_opts
));
1026 TEST_F(TestTypeSystemClang
, GetDeclContextByNameWhenMissingSymbolFile
) {
1027 // Test that a type system without a symbol file is handled gracefully.
1028 std::vector
<CompilerDecl
> decls
=
1029 m_ast
->DeclContextFindDeclByName(nullptr, ConstString("SomeName"), true);
1031 EXPECT_TRUE(decls
.empty());