1 //===-- TestTypeSystemClang.cpp -------------------------------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include "Plugins/ExpressionParser/Clang/ClangUtil.h" 10 #include "Plugins/TypeSystem/Clang/TypeSystemClang.h" 11 #include "TestingSupport/SubsystemRAII.h" 12 #include "TestingSupport/Symbol/ClangTestUtils.h" 13 #include "lldb/Core/Declaration.h" 14 #include "lldb/Host/FileSystem.h" 15 #include "lldb/Host/HostInfo.h" 16 #include "clang/AST/DeclCXX.h" 17 #include "clang/AST/DeclObjC.h" 18 #include "clang/AST/ExprCXX.h" 19 #include "gtest/gtest.h" 20 21 using namespace clang; 22 using namespace lldb; 23 using namespace lldb_private; 24 25 class TestTypeSystemClang : public testing::Test { 26 public: 27 SubsystemRAII<FileSystem, HostInfo> subsystems; 28 29 void SetUp() override { 30 m_ast.reset( 31 new TypeSystemClang("test ASTContext", HostInfo::GetTargetTriple())); 32 } 33 34 void TearDown() override { m_ast.reset(); } 35 36 protected: 37 std::unique_ptr<TypeSystemClang> m_ast; 38 39 QualType GetBasicQualType(BasicType type) const { 40 return ClangUtil::GetQualType(m_ast->GetBasicTypeFromAST(type)); 41 } 42 43 QualType GetBasicQualType(const char *name) const { 44 return ClangUtil::GetQualType( 45 m_ast->GetBuiltinTypeByName(ConstString(name))); 46 } 47 }; 48 49 TEST_F(TestTypeSystemClang, TestGetBasicTypeFromEnum) { 50 clang::ASTContext &context = m_ast->getASTContext(); 51 52 EXPECT_TRUE( 53 context.hasSameType(GetBasicQualType(eBasicTypeBool), context.BoolTy)); 54 EXPECT_TRUE( 55 context.hasSameType(GetBasicQualType(eBasicTypeChar), context.CharTy)); 56 EXPECT_TRUE(context.hasSameType(GetBasicQualType(eBasicTypeChar16), 57 context.Char16Ty)); 58 EXPECT_TRUE(context.hasSameType(GetBasicQualType(eBasicTypeChar32), 59 context.Char32Ty)); 60 EXPECT_TRUE(context.hasSameType(GetBasicQualType(eBasicTypeDouble), 61 context.DoubleTy)); 62 EXPECT_TRUE(context.hasSameType(GetBasicQualType(eBasicTypeDoubleComplex), 63 context.getComplexType(context.DoubleTy))); 64 EXPECT_TRUE( 65 context.hasSameType(GetBasicQualType(eBasicTypeFloat), context.FloatTy)); 66 EXPECT_TRUE(context.hasSameType(GetBasicQualType(eBasicTypeFloatComplex), 67 context.getComplexType(context.FloatTy))); 68 EXPECT_TRUE( 69 context.hasSameType(GetBasicQualType(eBasicTypeHalf), context.HalfTy)); 70 EXPECT_TRUE( 71 context.hasSameType(GetBasicQualType(eBasicTypeInt), context.IntTy)); 72 EXPECT_TRUE(context.hasSameType(GetBasicQualType(eBasicTypeInt128), 73 context.Int128Ty)); 74 EXPECT_TRUE( 75 context.hasSameType(GetBasicQualType(eBasicTypeLong), context.LongTy)); 76 EXPECT_TRUE(context.hasSameType(GetBasicQualType(eBasicTypeLongDouble), 77 context.LongDoubleTy)); 78 EXPECT_TRUE( 79 context.hasSameType(GetBasicQualType(eBasicTypeLongDoubleComplex), 80 context.getComplexType(context.LongDoubleTy))); 81 EXPECT_TRUE(context.hasSameType(GetBasicQualType(eBasicTypeLongLong), 82 context.LongLongTy)); 83 EXPECT_TRUE(context.hasSameType(GetBasicQualType(eBasicTypeNullPtr), 84 context.NullPtrTy)); 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())); 91 EXPECT_TRUE( 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)); 107 EXPECT_TRUE( 108 context.hasSameType(GetBasicQualType(eBasicTypeVoid), context.VoidTy)); 109 EXPECT_TRUE( 110 context.hasSameType(GetBasicQualType(eBasicTypeWChar), context.WCharTy)); 111 } 112 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")); 162 } 163 164 void VerifyEncodingAndBitSize(TypeSystemClang &clang_context, 165 lldb::Encoding encoding, unsigned int bit_size) { 166 clang::ASTContext &context = clang_context.getASTContext(); 167 168 CompilerType type = 169 clang_context.GetBuiltinTypeForEncodingAndBitSize(encoding, bit_size); 170 EXPECT_TRUE(type.IsValid()); 171 172 QualType qtype = ClangUtil::GetQualType(type); 173 EXPECT_FALSE(qtype.isNull()); 174 if (qtype.isNull()) 175 return; 176 177 uint64_t actual_size = context.getTypeSize(qtype); 178 EXPECT_EQ(bit_size, actual_size); 179 180 const clang::Type *type_ptr = qtype.getTypePtr(); 181 EXPECT_NE(nullptr, type_ptr); 182 if (!type_ptr) 183 return; 184 185 EXPECT_TRUE(type_ptr->isBuiltinType()); 186 switch (encoding) { 187 case eEncodingSint: 188 EXPECT_TRUE(type_ptr->isSignedIntegerType()); 189 break; 190 case eEncodingUint: 191 EXPECT_TRUE(type_ptr->isUnsignedIntegerType()); 192 break; 193 case eEncodingIEEE754: 194 EXPECT_TRUE(type_ptr->isFloatingType()); 195 break; 196 default: 197 FAIL() << "Unexpected encoding"; 198 break; 199 } 200 } 201 202 TEST_F(TestTypeSystemClang, TestBuiltinTypeForEncodingAndBitSize) { 203 // Make sure we can get types of every possible size in every possible 204 // encoding. 205 // We can't make any guarantee about which specific type we get, because the 206 // standard 207 // isn't that specific. We only need to make sure the compiler hands us some 208 // type that 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); 215 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); 221 222 VerifyEncodingAndBitSize(*m_ast, eEncodingIEEE754, 32); 223 VerifyEncodingAndBitSize(*m_ast, eEncodingIEEE754, 64); 224 } 225 226 TEST_F(TestTypeSystemClang, TestDisplayName) { 227 TypeSystemClang ast("some name", llvm::Triple()); 228 EXPECT_EQ("some name", ast.getDisplayName()); 229 } 230 231 TEST_F(TestTypeSystemClang, TestDisplayNameEmpty) { 232 TypeSystemClang ast("", llvm::Triple()); 233 EXPECT_EQ("", ast.getDisplayName()); 234 } 235 236 TEST_F(TestTypeSystemClang, TestGetEnumIntegerTypeInvalid) { 237 EXPECT_FALSE(m_ast->GetEnumerationIntegerType(CompilerType()).IsValid()); 238 } 239 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()); 244 } 245 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, 251 }; 252 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)); 257 258 TypeSystemClang ast("enum_ast", HostInfo::GetTargetTriple()); 259 CompilerType basic_compiler_type = ast.GetBasicType(basic_type); 260 EXPECT_TRUE(basic_compiler_type.IsValid()); 261 262 CompilerType enum_type = ast.CreateEnumerationType( 263 "my_enum", ast.GetTranslationUnitDecl(), OptionalClangModuleID(), 264 Declaration(), basic_compiler_type, scoped); 265 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()); 269 } 270 } 271 } 272 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); 280 EXPECT_FALSE(!ed); 281 EXPECT_EQ(ed->getOwningModuleID(), 100u); 282 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); 287 EXPECT_FALSE(!rd); 288 EXPECT_EQ(rd->getOwningModuleID(), 200u); 289 290 CompilerType class_type = 291 ast.CreateObjCClass("objc_class", ast.GetTranslationUnitDecl(), 292 OptionalClangModuleID(300), false, false); 293 auto *cd = TypeSystemClang::GetAsObjCInterfaceDecl(class_type); 294 EXPECT_FALSE(!cd); 295 EXPECT_EQ(cd->getOwningModuleID(), 300u); 296 } 297 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)); 309 310 // Default constructed type should fail 311 EXPECT_FALSE(ClangUtil::IsClangType(CompilerType())); 312 } 313 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); 318 QualType qt; 319 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()); 330 } 331 332 TEST_F(TestTypeSystemClang, TestConvertAccessTypeToAccessSpecifier) { 333 EXPECT_EQ(AS_none, 334 TypeSystemClang::ConvertAccessTypeToAccessSpecifier(eAccessNone)); 335 EXPECT_EQ(AS_none, TypeSystemClang::ConvertAccessTypeToAccessSpecifier( 336 eAccessPackage)); 337 EXPECT_EQ(AS_public, 338 TypeSystemClang::ConvertAccessTypeToAccessSpecifier(eAccessPublic)); 339 EXPECT_EQ(AS_private, TypeSystemClang::ConvertAccessTypeToAccessSpecifier( 340 eAccessPrivate)); 341 EXPECT_EQ(AS_protected, TypeSystemClang::ConvertAccessTypeToAccessSpecifier( 342 eAccessProtected)); 343 } 344 345 TEST_F(TestTypeSystemClang, TestUnifyAccessSpecifiers) { 346 // Unifying two of the same type should return the same type 347 EXPECT_EQ(AS_public, 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)); 353 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)); 367 368 // None is stricter than everything (by convention) 369 EXPECT_EQ(AS_none, 370 TypeSystemClang::UnifyAccessSpecifiers(AS_none, AS_public)); 371 EXPECT_EQ(AS_none, 372 TypeSystemClang::UnifyAccessSpecifiers(AS_none, AS_protected)); 373 EXPECT_EQ(AS_none, 374 TypeSystemClang::UnifyAccessSpecifiers(AS_none, AS_private)); 375 EXPECT_EQ(AS_none, 376 TypeSystemClang::UnifyAccessSpecifiers(AS_public, AS_none)); 377 EXPECT_EQ(AS_none, 378 TypeSystemClang::UnifyAccessSpecifiers(AS_protected, AS_none)); 379 EXPECT_EQ(AS_none, 380 TypeSystemClang::UnifyAccessSpecifiers(AS_private, AS_none)); 381 } 382 383 TEST_F(TestTypeSystemClang, TestRecordHasFields) { 384 CompilerType int_type = m_ast->GetBasicType(eBasicTypeInt); 385 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); 392 393 RecordDecl *empty_base_decl = TypeSystemClang::GetAsRecordDecl(empty_base); 394 EXPECT_NE(nullptr, empty_base_decl); 395 EXPECT_FALSE(TypeSystemClang::RecordHasFields(empty_base_decl)); 396 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)); 410 411 std::vector<std::unique_ptr<clang::CXXBaseSpecifier>> bases; 412 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(), 423 std::move(bases)); 424 TypeSystemClang::CompleteTagDeclarationDefinition(empty_derived); 425 EXPECT_TRUE(result); 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)); 432 EXPECT_TRUE( 433 TypeSystemClang::RecordHasFields(empty_derived_non_empty_base_decl)); 434 435 // Test that a record with no direct fields, but fields in a virtual base 436 // returns true 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(), 446 std::move(bases)); 447 TypeSystemClang::CompleteTagDeclarationDefinition(empty_derived2); 448 EXPECT_TRUE(result); 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)); 455 EXPECT_TRUE( 456 TypeSystemClang::RecordHasFields(empty_derived_non_empty_vbase_decl)); 457 } 458 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)); 467 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); 473 474 // foo<int, 47> 475 ClassTemplateSpecializationDecl *spec_decl = 476 m_ast->CreateClassTemplateSpecializationDecl( 477 m_ast->GetTranslationUnitDecl(), OptionalClangModuleID(), decl, 478 TTK_Struct, infos); 479 ASSERT_NE(spec_decl, nullptr); 480 CompilerType type = m_ast->CreateClassTemplateSpecializationType(spec_decl); 481 ASSERT_TRUE(type); 482 m_ast->StartTagDeclarationDefinition(type); 483 m_ast->CompleteTagDeclarationDefinition(type); 484 485 // typedef foo<int, 47> foo_def; 486 CompilerType typedef_type = type.CreateTypedef( 487 "foo_def", m_ast->CreateDeclContext(m_ast->GetTranslationUnitDecl()), 0); 488 489 CompilerType auto_type( 490 m_ast.get(), 491 m_ast->getASTContext() 492 .getAutoType(ClangUtil::GetCanonicalQualType(typedef_type), 493 clang::AutoTypeKeyword::Auto, false) 494 .getAsOpaquePtr()); 495 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()); 500 501 EXPECT_EQ(m_ast->GetTemplateArgumentKind(t.GetOpaqueQualType(), 0), 502 eTemplateArgumentKindType); 503 EXPECT_EQ(m_ast->GetTypeTemplateArgument(t.GetOpaqueQualType(), 0), 504 int_type); 505 EXPECT_EQ(llvm::None, 506 m_ast->GetIntegralTemplateArgument(t.GetOpaqueQualType(), 0)); 507 508 EXPECT_EQ(m_ast->GetTemplateArgumentKind(t.GetOpaqueQualType(), 1), 509 eTemplateArgumentKindIntegral); 510 EXPECT_EQ(m_ast->GetTypeTemplateArgument(t.GetOpaqueQualType(), 1), 511 CompilerType()); 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); 516 } 517 } 518 519 class TestCreateClassTemplateDecl : public TestTypeSystemClang { 520 protected: 521 /// The class templates created so far by the Expect* functions below. 522 llvm::DenseSet<ClassTemplateDecl *> m_created_templates; 523 524 /// Utility function for creating a class template. 525 ClassTemplateDecl * 526 CreateClassTemplate(const TypeSystemClang::TemplateParameterInfos &infos) { 527 ClassTemplateDecl *decl = m_ast->CreateClassTemplateDecl( 528 m_ast->GetTranslationUnitDecl(), OptionalClangModuleID(), eAccessPublic, 529 "foo", TTK_Struct, infos); 530 return decl; 531 } 532 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. 538 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); 548 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; 557 } 558 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. 564 void 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); 574 } 575 }; 576 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.) 582 583 // This describes a class template *instantiation* from which we will infer 584 // the structure of the class template. 585 TypeSystemClang::TemplateParameterInfos infos; 586 587 // Test an empty template parameter list: <> 588 ExpectNewTemplate("<>", infos); 589 590 // Test that <typename T> with T = int creates a new template. 591 infos.names = {"T"}; 592 infos.args = {TemplateArgument(m_ast->getASTContext().IntTy)}; 593 ClassTemplateDecl *single_type_arg = ExpectNewTemplate("<typename T>", infos); 594 595 // Test that changing the parameter name doesn't create a new class template. 596 infos.names = {"A"}; 597 ExpectReusedTemplate("<typename A> (A = int)", infos, single_type_arg); 598 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); 602 603 // Test that <typename A, signed char I> creates a new template with A = int 604 // and I = 47; 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); 611 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); 620 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); 628 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); 635 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); 641 } 642 643 TEST_F(TestCreateClassTemplateDecl, FindExistingTemplatesWithParameterPack) { 644 // The same as FindExistingTemplates but for templates with parameter packs. 645 646 TypeSystemClang::TemplateParameterInfos infos; 647 infos.packed_args = 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); 654 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. 658 infos.packed_args = 659 std::make_unique<TypeSystemClang::TemplateParameterInfos>(); 660 ExpectReusedTemplate("<...> (no values in pack)", infos, type_pack); 661 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); 667 668 // Change the number of pack values. 669 infos.packed_args->args = {TemplateArgument(m_ast->getASTContext().IntTy)}; 670 ExpectReusedTemplate("<typename ...> (int)", infos, type_pack); 671 672 // The names of the pack values shouldn't matter. 673 infos.packed_args->names = {"A", "B"}; 674 ExpectReusedTemplate("<typename ...> (int)", infos, type_pack); 675 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); 681 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); 687 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); 693 694 // Prependinding a non-pack parameter will create a new template. 695 infos.names = {"T"}; 696 infos.args = {TemplateArgument(m_ast->getASTContext().IntTy)}; 697 ExpectNewTemplate("<typename T, long...> (T = int, long = 1)", infos); 698 } 699 700 TEST_F(TestTypeSystemClang, OnlyPackName) { 701 TypeSystemClang::TemplateParameterInfos infos; 702 infos.pack_name = "A"; 703 EXPECT_FALSE(infos.IsValid()); 704 } 705 706 static QualType makeConstInt(clang::ASTContext &ctxt) { 707 QualType result(ctxt.IntTy); 708 result.addConst(); 709 return result; 710 } 711 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())); 717 } 718 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())); 723 } 724 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())); 730 } 731 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())); 737 } 738 739 TEST_F(TestTypeSystemClang, TestFunctionTemplateConstruction) { 740 // Tests creating a function template. 741 742 CompilerType int_type = m_ast->GetBasicType(lldb::eBasicTypeInt); 743 clang::TranslationUnitDecl *TU = m_ast->GetTranslationUnitDecl(); 744 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, 750 false); 751 TypeSystemClang::TemplateParameterInfos empty_params; 752 753 // Create the actual function template. 754 clang::FunctionTemplateDecl *func_template = 755 m_ast->CreateFunctionTemplateDecl(TU, OptionalClangModuleID(), func, 756 empty_params); 757 758 EXPECT_EQ(TU, func_template->getDeclContext()); 759 EXPECT_EQ("foo", func_template->getName()); 760 EXPECT_EQ(clang::AccessSpecifier::AS_none, func_template->getAccess()); 761 } 762 763 TEST_F(TestTypeSystemClang, TestFunctionTemplateInRecordConstruction) { 764 // Tests creating a function template inside a record. 765 766 CompilerType int_type = m_ast->GetBasicType(lldb::eBasicTypeInt); 767 clang::TranslationUnitDecl *TU = m_ast->GetTranslationUnitDecl(); 768 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); 773 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, 782 false); 783 TypeSystemClang::TemplateParameterInfos empty_params; 784 785 // Create the actual function template. 786 clang::FunctionTemplateDecl *func_template = 787 m_ast->CreateFunctionTemplateDecl(record, OptionalClangModuleID(), func, 788 empty_params); 789 790 EXPECT_EQ(record, func_template->getDeclContext()); 791 EXPECT_EQ("foo", func_template->getName()); 792 EXPECT_EQ(clang::AccessSpecifier::AS_public, func_template->getAccess()); 793 } 794 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. 802 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); 807 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); 824 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()); 835 } 836 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); 844 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. 853 { 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); 862 } 863 // Create a copy constructor. 864 { 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); 873 } 874 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()); 879 } 880 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()); 890 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, 902 objc_direct); 903 ASSERT_NE(method, nullptr); 904 905 // The interface decl should still have external lexical storage. 906 EXPECT_TRUE(interface->hasExternalLexicalStorage()); 907 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"); 913 } 914 915 TEST_F(TestTypeSystemClang, GetFullyUnqualifiedType) { 916 CompilerType bool_ = m_ast->GetBasicType(eBasicTypeBool); 917 CompilerType cv_bool = bool_.AddConstModifier().AddVolatileModifier(); 918 919 // const volatile bool -> bool 920 EXPECT_EQ(bool_, cv_bool.GetFullyUnqualifiedType()); 921 922 // const volatile bool[47] -> bool[47] 923 EXPECT_EQ(bool_.GetArrayType(47), 924 cv_bool.GetArrayType(47).GetFullyUnqualifiedType()); 925 926 // const volatile bool[47][42] -> bool[47][42] 927 EXPECT_EQ( 928 bool_.GetArrayType(42).GetArrayType(47), 929 cv_bool.GetArrayType(42).GetArrayType(47).GetFullyUnqualifiedType()); 930 931 // const volatile bool * -> bool * 932 EXPECT_EQ(bool_.GetPointerType(), 933 cv_bool.GetPointerType().GetFullyUnqualifiedType()); 934 935 // const volatile bool *[47] -> bool *[47] 936 EXPECT_EQ( 937 bool_.GetPointerType().GetArrayType(47), 938 cv_bool.GetPointerType().GetArrayType(47).GetFullyUnqualifiedType()); 939 } 940 941 TEST(TestScratchTypeSystemClang, InferSubASTFromLangOpts) { 942 LangOptions lang_opts; 943 EXPECT_EQ( 944 ScratchTypeSystemClang::DefaultAST, 945 ScratchTypeSystemClang::InferIsolatedASTKindFromLangOpts(lang_opts)); 946 947 lang_opts.Modules = true; 948 EXPECT_EQ( 949 ScratchTypeSystemClang::IsolatedASTKind::CppModules, 950 ScratchTypeSystemClang::InferIsolatedASTKindFromLangOpts(lang_opts)); 951 } 952 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); 962 } 963 964