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