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.DoubleComplexTy)); 64 EXPECT_TRUE( 65 context.hasSameType(GetBasicQualType(eBasicTypeFloat), context.FloatTy)); 66 EXPECT_TRUE(context.hasSameType(GetBasicQualType(eBasicTypeFloatComplex), 67 context.FloatComplexTy)); 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(context.hasSameType(GetBasicQualType(eBasicTypeLongDoubleComplex), 79 context.LongDoubleComplexTy)); 80 EXPECT_TRUE(context.hasSameType(GetBasicQualType(eBasicTypeLongLong), 81 context.LongLongTy)); 82 EXPECT_TRUE(context.hasSameType(GetBasicQualType(eBasicTypeNullPtr), 83 context.NullPtrTy)); 84 EXPECT_TRUE(context.hasSameType(GetBasicQualType(eBasicTypeObjCClass), 85 context.getObjCClassType())); 86 EXPECT_TRUE(context.hasSameType(GetBasicQualType(eBasicTypeObjCID), 87 context.getObjCIdType())); 88 EXPECT_TRUE(context.hasSameType(GetBasicQualType(eBasicTypeObjCSel), 89 context.getObjCSelType())); 90 EXPECT_TRUE( 91 context.hasSameType(GetBasicQualType(eBasicTypeShort), context.ShortTy)); 92 EXPECT_TRUE(context.hasSameType(GetBasicQualType(eBasicTypeSignedChar), 93 context.SignedCharTy)); 94 EXPECT_TRUE(context.hasSameType(GetBasicQualType(eBasicTypeUnsignedChar), 95 context.UnsignedCharTy)); 96 EXPECT_TRUE(context.hasSameType(GetBasicQualType(eBasicTypeUnsignedInt), 97 context.UnsignedIntTy)); 98 EXPECT_TRUE(context.hasSameType(GetBasicQualType(eBasicTypeUnsignedInt128), 99 context.UnsignedInt128Ty)); 100 EXPECT_TRUE(context.hasSameType(GetBasicQualType(eBasicTypeUnsignedLong), 101 context.UnsignedLongTy)); 102 EXPECT_TRUE(context.hasSameType(GetBasicQualType(eBasicTypeUnsignedLongLong), 103 context.UnsignedLongLongTy)); 104 EXPECT_TRUE(context.hasSameType(GetBasicQualType(eBasicTypeUnsignedShort), 105 context.UnsignedShortTy)); 106 EXPECT_TRUE( 107 context.hasSameType(GetBasicQualType(eBasicTypeVoid), context.VoidTy)); 108 EXPECT_TRUE( 109 context.hasSameType(GetBasicQualType(eBasicTypeWChar), context.WCharTy)); 110 } 111 112 TEST_F(TestTypeSystemClang, TestGetBasicTypeFromName) { 113 EXPECT_EQ(GetBasicQualType(eBasicTypeChar), GetBasicQualType("char")); 114 EXPECT_EQ(GetBasicQualType(eBasicTypeSignedChar), 115 GetBasicQualType("signed char")); 116 EXPECT_EQ(GetBasicQualType(eBasicTypeUnsignedChar), 117 GetBasicQualType("unsigned char")); 118 EXPECT_EQ(GetBasicQualType(eBasicTypeWChar), GetBasicQualType("wchar_t")); 119 EXPECT_EQ(GetBasicQualType(eBasicTypeSignedWChar), 120 GetBasicQualType("signed wchar_t")); 121 EXPECT_EQ(GetBasicQualType(eBasicTypeUnsignedWChar), 122 GetBasicQualType("unsigned wchar_t")); 123 EXPECT_EQ(GetBasicQualType(eBasicTypeShort), GetBasicQualType("short")); 124 EXPECT_EQ(GetBasicQualType(eBasicTypeShort), GetBasicQualType("short int")); 125 EXPECT_EQ(GetBasicQualType(eBasicTypeUnsignedShort), 126 GetBasicQualType("unsigned short")); 127 EXPECT_EQ(GetBasicQualType(eBasicTypeUnsignedShort), 128 GetBasicQualType("unsigned short int")); 129 EXPECT_EQ(GetBasicQualType(eBasicTypeInt), GetBasicQualType("int")); 130 EXPECT_EQ(GetBasicQualType(eBasicTypeInt), GetBasicQualType("signed int")); 131 EXPECT_EQ(GetBasicQualType(eBasicTypeUnsignedInt), 132 GetBasicQualType("unsigned int")); 133 EXPECT_EQ(GetBasicQualType(eBasicTypeUnsignedInt), 134 GetBasicQualType("unsigned")); 135 EXPECT_EQ(GetBasicQualType(eBasicTypeLong), GetBasicQualType("long")); 136 EXPECT_EQ(GetBasicQualType(eBasicTypeLong), GetBasicQualType("long int")); 137 EXPECT_EQ(GetBasicQualType(eBasicTypeUnsignedLong), 138 GetBasicQualType("unsigned long")); 139 EXPECT_EQ(GetBasicQualType(eBasicTypeUnsignedLong), 140 GetBasicQualType("unsigned long int")); 141 EXPECT_EQ(GetBasicQualType(eBasicTypeLongLong), 142 GetBasicQualType("long long")); 143 EXPECT_EQ(GetBasicQualType(eBasicTypeLongLong), 144 GetBasicQualType("long long int")); 145 EXPECT_EQ(GetBasicQualType(eBasicTypeUnsignedLongLong), 146 GetBasicQualType("unsigned long long")); 147 EXPECT_EQ(GetBasicQualType(eBasicTypeUnsignedLongLong), 148 GetBasicQualType("unsigned long long int")); 149 EXPECT_EQ(GetBasicQualType(eBasicTypeInt128), GetBasicQualType("__int128_t")); 150 EXPECT_EQ(GetBasicQualType(eBasicTypeUnsignedInt128), 151 GetBasicQualType("__uint128_t")); 152 EXPECT_EQ(GetBasicQualType(eBasicTypeVoid), GetBasicQualType("void")); 153 EXPECT_EQ(GetBasicQualType(eBasicTypeBool), GetBasicQualType("bool")); 154 EXPECT_EQ(GetBasicQualType(eBasicTypeFloat), GetBasicQualType("float")); 155 EXPECT_EQ(GetBasicQualType(eBasicTypeDouble), GetBasicQualType("double")); 156 EXPECT_EQ(GetBasicQualType(eBasicTypeLongDouble), 157 GetBasicQualType("long double")); 158 EXPECT_EQ(GetBasicQualType(eBasicTypeObjCID), GetBasicQualType("id")); 159 EXPECT_EQ(GetBasicQualType(eBasicTypeObjCSel), GetBasicQualType("SEL")); 160 EXPECT_EQ(GetBasicQualType(eBasicTypeNullPtr), GetBasicQualType("nullptr")); 161 } 162 163 void VerifyEncodingAndBitSize(TypeSystemClang &clang_context, 164 lldb::Encoding encoding, unsigned int bit_size) { 165 clang::ASTContext &context = clang_context.getASTContext(); 166 167 CompilerType type = 168 clang_context.GetBuiltinTypeForEncodingAndBitSize(encoding, bit_size); 169 EXPECT_TRUE(type.IsValid()); 170 171 QualType qtype = ClangUtil::GetQualType(type); 172 EXPECT_FALSE(qtype.isNull()); 173 if (qtype.isNull()) 174 return; 175 176 uint64_t actual_size = context.getTypeSize(qtype); 177 EXPECT_EQ(bit_size, actual_size); 178 179 const clang::Type *type_ptr = qtype.getTypePtr(); 180 EXPECT_NE(nullptr, type_ptr); 181 if (!type_ptr) 182 return; 183 184 EXPECT_TRUE(type_ptr->isBuiltinType()); 185 switch (encoding) { 186 case eEncodingSint: 187 EXPECT_TRUE(type_ptr->isSignedIntegerType()); 188 break; 189 case eEncodingUint: 190 EXPECT_TRUE(type_ptr->isUnsignedIntegerType()); 191 break; 192 case eEncodingIEEE754: 193 EXPECT_TRUE(type_ptr->isFloatingType()); 194 break; 195 default: 196 FAIL() << "Unexpected encoding"; 197 break; 198 } 199 } 200 201 TEST_F(TestTypeSystemClang, TestBuiltinTypeForEncodingAndBitSize) { 202 // Make sure we can get types of every possible size in every possible 203 // encoding. 204 // We can't make any guarantee about which specific type we get, because the 205 // standard 206 // isn't that specific. We only need to make sure the compiler hands us some 207 // type that 208 // is both a builtin type and matches the requested bit size. 209 VerifyEncodingAndBitSize(*m_ast, eEncodingSint, 8); 210 VerifyEncodingAndBitSize(*m_ast, eEncodingSint, 16); 211 VerifyEncodingAndBitSize(*m_ast, eEncodingSint, 32); 212 VerifyEncodingAndBitSize(*m_ast, eEncodingSint, 64); 213 VerifyEncodingAndBitSize(*m_ast, eEncodingSint, 128); 214 215 VerifyEncodingAndBitSize(*m_ast, eEncodingUint, 8); 216 VerifyEncodingAndBitSize(*m_ast, eEncodingUint, 16); 217 VerifyEncodingAndBitSize(*m_ast, eEncodingUint, 32); 218 VerifyEncodingAndBitSize(*m_ast, eEncodingUint, 64); 219 VerifyEncodingAndBitSize(*m_ast, eEncodingUint, 128); 220 221 VerifyEncodingAndBitSize(*m_ast, eEncodingIEEE754, 32); 222 VerifyEncodingAndBitSize(*m_ast, eEncodingIEEE754, 64); 223 } 224 225 TEST_F(TestTypeSystemClang, TestDisplayName) { 226 TypeSystemClang ast("some name", llvm::Triple()); 227 EXPECT_EQ("some name", ast.getDisplayName()); 228 } 229 230 TEST_F(TestTypeSystemClang, TestDisplayNameEmpty) { 231 TypeSystemClang ast("", llvm::Triple()); 232 EXPECT_EQ("", ast.getDisplayName()); 233 } 234 235 TEST_F(TestTypeSystemClang, TestGetEnumIntegerTypeInvalid) { 236 EXPECT_FALSE(m_ast->GetEnumerationIntegerType(CompilerType()).IsValid()); 237 } 238 239 TEST_F(TestTypeSystemClang, TestGetEnumIntegerTypeUnexpectedType) { 240 CompilerType int_type = m_ast->GetBasicType(lldb::eBasicTypeInt); 241 CompilerType t = m_ast->GetEnumerationIntegerType(int_type); 242 EXPECT_FALSE(t.IsValid()); 243 } 244 245 TEST_F(TestTypeSystemClang, TestGetEnumIntegerTypeBasicTypes) { 246 // All possible underlying integer types of enums. 247 const std::vector<lldb::BasicType> types_to_test = { 248 eBasicTypeInt, eBasicTypeUnsignedInt, eBasicTypeLong, 249 eBasicTypeUnsignedLong, eBasicTypeLongLong, eBasicTypeUnsignedLongLong, 250 }; 251 252 for (bool scoped : {true, false}) { 253 SCOPED_TRACE("scoped: " + std::to_string(scoped)); 254 for (lldb::BasicType basic_type : types_to_test) { 255 SCOPED_TRACE(std::to_string(basic_type)); 256 257 TypeSystemClang ast("enum_ast", HostInfo::GetTargetTriple()); 258 CompilerType basic_compiler_type = ast.GetBasicType(basic_type); 259 EXPECT_TRUE(basic_compiler_type.IsValid()); 260 261 CompilerType enum_type = ast.CreateEnumerationType( 262 "my_enum", ast.GetTranslationUnitDecl(), OptionalClangModuleID(), 263 Declaration(), basic_compiler_type, scoped); 264 265 CompilerType t = ast.GetEnumerationIntegerType(enum_type); 266 // Check that the type we put in at the start is found again. 267 EXPECT_EQ(basic_compiler_type.GetTypeName(), t.GetTypeName()); 268 } 269 } 270 } 271 272 TEST_F(TestTypeSystemClang, TestOwningModule) { 273 TypeSystemClang ast("module_ast", HostInfo::GetTargetTriple()); 274 CompilerType basic_compiler_type = ast.GetBasicType(BasicType::eBasicTypeInt); 275 CompilerType enum_type = ast.CreateEnumerationType( 276 "my_enum", ast.GetTranslationUnitDecl(), OptionalClangModuleID(100), 277 Declaration(), basic_compiler_type, false); 278 auto *ed = TypeSystemClang::GetAsEnumDecl(enum_type); 279 EXPECT_FALSE(!ed); 280 EXPECT_EQ(ed->getOwningModuleID(), 100u); 281 282 CompilerType record_type = ast.CreateRecordType( 283 nullptr, OptionalClangModuleID(200), lldb::eAccessPublic, "FooRecord", 284 clang::TTK_Struct, lldb::eLanguageTypeC_plus_plus, nullptr); 285 auto *rd = TypeSystemClang::GetAsRecordDecl(record_type); 286 EXPECT_FALSE(!rd); 287 EXPECT_EQ(rd->getOwningModuleID(), 200u); 288 289 CompilerType class_type = 290 ast.CreateObjCClass("objc_class", ast.GetTranslationUnitDecl(), 291 OptionalClangModuleID(300), false, false); 292 auto *cd = TypeSystemClang::GetAsObjCInterfaceDecl(class_type); 293 EXPECT_FALSE(!cd); 294 EXPECT_EQ(cd->getOwningModuleID(), 300u); 295 } 296 297 TEST_F(TestTypeSystemClang, TestIsClangType) { 298 clang::ASTContext &context = m_ast->getASTContext(); 299 lldb::opaque_compiler_type_t bool_ctype = 300 TypeSystemClang::GetOpaqueCompilerType(&context, lldb::eBasicTypeBool); 301 CompilerType bool_type(m_ast.get(), bool_ctype); 302 CompilerType record_type = m_ast->CreateRecordType( 303 nullptr, OptionalClangModuleID(100), lldb::eAccessPublic, "FooRecord", 304 clang::TTK_Struct, lldb::eLanguageTypeC_plus_plus, nullptr); 305 // Clang builtin type and record type should pass 306 EXPECT_TRUE(ClangUtil::IsClangType(bool_type)); 307 EXPECT_TRUE(ClangUtil::IsClangType(record_type)); 308 309 // Default constructed type should fail 310 EXPECT_FALSE(ClangUtil::IsClangType(CompilerType())); 311 } 312 313 TEST_F(TestTypeSystemClang, TestRemoveFastQualifiers) { 314 CompilerType record_type = m_ast->CreateRecordType( 315 nullptr, OptionalClangModuleID(), lldb::eAccessPublic, "FooRecord", 316 clang::TTK_Struct, lldb::eLanguageTypeC_plus_plus, nullptr); 317 QualType qt; 318 319 qt = ClangUtil::GetQualType(record_type); 320 EXPECT_EQ(0u, qt.getLocalFastQualifiers()); 321 record_type = record_type.AddConstModifier(); 322 record_type = record_type.AddVolatileModifier(); 323 record_type = record_type.AddRestrictModifier(); 324 qt = ClangUtil::GetQualType(record_type); 325 EXPECT_NE(0u, qt.getLocalFastQualifiers()); 326 record_type = ClangUtil::RemoveFastQualifiers(record_type); 327 qt = ClangUtil::GetQualType(record_type); 328 EXPECT_EQ(0u, qt.getLocalFastQualifiers()); 329 } 330 331 TEST_F(TestTypeSystemClang, TestConvertAccessTypeToAccessSpecifier) { 332 EXPECT_EQ(AS_none, 333 TypeSystemClang::ConvertAccessTypeToAccessSpecifier(eAccessNone)); 334 EXPECT_EQ(AS_none, TypeSystemClang::ConvertAccessTypeToAccessSpecifier( 335 eAccessPackage)); 336 EXPECT_EQ(AS_public, 337 TypeSystemClang::ConvertAccessTypeToAccessSpecifier(eAccessPublic)); 338 EXPECT_EQ(AS_private, TypeSystemClang::ConvertAccessTypeToAccessSpecifier( 339 eAccessPrivate)); 340 EXPECT_EQ(AS_protected, TypeSystemClang::ConvertAccessTypeToAccessSpecifier( 341 eAccessProtected)); 342 } 343 344 TEST_F(TestTypeSystemClang, TestUnifyAccessSpecifiers) { 345 // Unifying two of the same type should return the same type 346 EXPECT_EQ(AS_public, 347 TypeSystemClang::UnifyAccessSpecifiers(AS_public, AS_public)); 348 EXPECT_EQ(AS_private, 349 TypeSystemClang::UnifyAccessSpecifiers(AS_private, AS_private)); 350 EXPECT_EQ(AS_protected, 351 TypeSystemClang::UnifyAccessSpecifiers(AS_protected, AS_protected)); 352 353 // Otherwise the result should be the strictest of the two. 354 EXPECT_EQ(AS_private, 355 TypeSystemClang::UnifyAccessSpecifiers(AS_private, AS_public)); 356 EXPECT_EQ(AS_private, 357 TypeSystemClang::UnifyAccessSpecifiers(AS_private, AS_protected)); 358 EXPECT_EQ(AS_private, 359 TypeSystemClang::UnifyAccessSpecifiers(AS_public, AS_private)); 360 EXPECT_EQ(AS_private, 361 TypeSystemClang::UnifyAccessSpecifiers(AS_protected, AS_private)); 362 EXPECT_EQ(AS_protected, 363 TypeSystemClang::UnifyAccessSpecifiers(AS_protected, AS_public)); 364 EXPECT_EQ(AS_protected, 365 TypeSystemClang::UnifyAccessSpecifiers(AS_public, AS_protected)); 366 367 // None is stricter than everything (by convention) 368 EXPECT_EQ(AS_none, 369 TypeSystemClang::UnifyAccessSpecifiers(AS_none, AS_public)); 370 EXPECT_EQ(AS_none, 371 TypeSystemClang::UnifyAccessSpecifiers(AS_none, AS_protected)); 372 EXPECT_EQ(AS_none, 373 TypeSystemClang::UnifyAccessSpecifiers(AS_none, AS_private)); 374 EXPECT_EQ(AS_none, 375 TypeSystemClang::UnifyAccessSpecifiers(AS_public, AS_none)); 376 EXPECT_EQ(AS_none, 377 TypeSystemClang::UnifyAccessSpecifiers(AS_protected, AS_none)); 378 EXPECT_EQ(AS_none, 379 TypeSystemClang::UnifyAccessSpecifiers(AS_private, AS_none)); 380 } 381 382 TEST_F(TestTypeSystemClang, TestRecordHasFields) { 383 CompilerType int_type = m_ast->GetBasicType(eBasicTypeInt); 384 385 // Test that a record with no fields returns false 386 CompilerType empty_base = m_ast->CreateRecordType( 387 nullptr, OptionalClangModuleID(), lldb::eAccessPublic, "EmptyBase", 388 clang::TTK_Struct, lldb::eLanguageTypeC_plus_plus, nullptr); 389 TypeSystemClang::StartTagDeclarationDefinition(empty_base); 390 TypeSystemClang::CompleteTagDeclarationDefinition(empty_base); 391 392 RecordDecl *empty_base_decl = TypeSystemClang::GetAsRecordDecl(empty_base); 393 EXPECT_NE(nullptr, empty_base_decl); 394 EXPECT_FALSE(TypeSystemClang::RecordHasFields(empty_base_decl)); 395 396 // Test that a record with direct fields returns true 397 CompilerType non_empty_base = m_ast->CreateRecordType( 398 nullptr, OptionalClangModuleID(), lldb::eAccessPublic, "NonEmptyBase", 399 clang::TTK_Struct, lldb::eLanguageTypeC_plus_plus, nullptr); 400 TypeSystemClang::StartTagDeclarationDefinition(non_empty_base); 401 FieldDecl *non_empty_base_field_decl = m_ast->AddFieldToRecordType( 402 non_empty_base, "MyField", int_type, eAccessPublic, 0); 403 TypeSystemClang::CompleteTagDeclarationDefinition(non_empty_base); 404 RecordDecl *non_empty_base_decl = 405 TypeSystemClang::GetAsRecordDecl(non_empty_base); 406 EXPECT_NE(nullptr, non_empty_base_decl); 407 EXPECT_NE(nullptr, non_empty_base_field_decl); 408 EXPECT_TRUE(TypeSystemClang::RecordHasFields(non_empty_base_decl)); 409 410 std::vector<std::unique_ptr<clang::CXXBaseSpecifier>> bases; 411 412 // Test that a record with no direct fields, but fields in a base returns true 413 CompilerType empty_derived = m_ast->CreateRecordType( 414 nullptr, OptionalClangModuleID(), lldb::eAccessPublic, "EmptyDerived", 415 clang::TTK_Struct, lldb::eLanguageTypeC_plus_plus, nullptr); 416 TypeSystemClang::StartTagDeclarationDefinition(empty_derived); 417 std::unique_ptr<clang::CXXBaseSpecifier> non_empty_base_spec = 418 m_ast->CreateBaseClassSpecifier(non_empty_base.GetOpaqueQualType(), 419 lldb::eAccessPublic, false, false); 420 bases.push_back(std::move(non_empty_base_spec)); 421 bool result = m_ast->TransferBaseClasses(empty_derived.GetOpaqueQualType(), 422 std::move(bases)); 423 TypeSystemClang::CompleteTagDeclarationDefinition(empty_derived); 424 EXPECT_TRUE(result); 425 CXXRecordDecl *empty_derived_non_empty_base_cxx_decl = 426 m_ast->GetAsCXXRecordDecl(empty_derived.GetOpaqueQualType()); 427 RecordDecl *empty_derived_non_empty_base_decl = 428 TypeSystemClang::GetAsRecordDecl(empty_derived); 429 EXPECT_EQ(1u, TypeSystemClang::GetNumBaseClasses( 430 empty_derived_non_empty_base_cxx_decl, false)); 431 EXPECT_TRUE( 432 TypeSystemClang::RecordHasFields(empty_derived_non_empty_base_decl)); 433 434 // Test that a record with no direct fields, but fields in a virtual base 435 // returns true 436 CompilerType empty_derived2 = m_ast->CreateRecordType( 437 nullptr, OptionalClangModuleID(), lldb::eAccessPublic, "EmptyDerived2", 438 clang::TTK_Struct, lldb::eLanguageTypeC_plus_plus, nullptr); 439 TypeSystemClang::StartTagDeclarationDefinition(empty_derived2); 440 std::unique_ptr<CXXBaseSpecifier> non_empty_vbase_spec = 441 m_ast->CreateBaseClassSpecifier(non_empty_base.GetOpaqueQualType(), 442 lldb::eAccessPublic, true, false); 443 bases.push_back(std::move(non_empty_vbase_spec)); 444 result = m_ast->TransferBaseClasses(empty_derived2.GetOpaqueQualType(), 445 std::move(bases)); 446 TypeSystemClang::CompleteTagDeclarationDefinition(empty_derived2); 447 EXPECT_TRUE(result); 448 CXXRecordDecl *empty_derived_non_empty_vbase_cxx_decl = 449 m_ast->GetAsCXXRecordDecl(empty_derived2.GetOpaqueQualType()); 450 RecordDecl *empty_derived_non_empty_vbase_decl = 451 TypeSystemClang::GetAsRecordDecl(empty_derived2); 452 EXPECT_EQ(1u, TypeSystemClang::GetNumBaseClasses( 453 empty_derived_non_empty_vbase_cxx_decl, false)); 454 EXPECT_TRUE( 455 TypeSystemClang::RecordHasFields(empty_derived_non_empty_vbase_decl)); 456 } 457 458 TEST_F(TestTypeSystemClang, TemplateArguments) { 459 TypeSystemClang::TemplateParameterInfos infos; 460 infos.names.push_back("T"); 461 infos.args.push_back(TemplateArgument(m_ast->getASTContext().IntTy)); 462 infos.names.push_back("I"); 463 llvm::APSInt arg(llvm::APInt(8, 47)); 464 infos.args.push_back(TemplateArgument(m_ast->getASTContext(), arg, 465 m_ast->getASTContext().IntTy)); 466 467 // template<typename T, int I> struct foo; 468 ClassTemplateDecl *decl = m_ast->CreateClassTemplateDecl( 469 m_ast->GetTranslationUnitDecl(), OptionalClangModuleID(), eAccessPublic, 470 "foo", TTK_Struct, infos); 471 ASSERT_NE(decl, nullptr); 472 473 // foo<int, 47> 474 ClassTemplateSpecializationDecl *spec_decl = 475 m_ast->CreateClassTemplateSpecializationDecl( 476 m_ast->GetTranslationUnitDecl(), OptionalClangModuleID(), decl, 477 TTK_Struct, infos); 478 ASSERT_NE(spec_decl, nullptr); 479 CompilerType type = m_ast->CreateClassTemplateSpecializationType(spec_decl); 480 ASSERT_TRUE(type); 481 m_ast->StartTagDeclarationDefinition(type); 482 m_ast->CompleteTagDeclarationDefinition(type); 483 484 // typedef foo<int, 47> foo_def; 485 CompilerType typedef_type = type.CreateTypedef( 486 "foo_def", m_ast->CreateDeclContext(m_ast->GetTranslationUnitDecl()), 0); 487 488 CompilerType auto_type( 489 m_ast.get(), 490 m_ast->getASTContext() 491 .getAutoType(ClangUtil::GetCanonicalQualType(typedef_type), 492 clang::AutoTypeKeyword::Auto, false) 493 .getAsOpaquePtr()); 494 495 CompilerType int_type(m_ast.get(), 496 m_ast->getASTContext().IntTy.getAsOpaquePtr()); 497 for (CompilerType t : {type, typedef_type, auto_type}) { 498 SCOPED_TRACE(t.GetTypeName().AsCString()); 499 500 EXPECT_EQ(m_ast->GetTemplateArgumentKind(t.GetOpaqueQualType(), 0), 501 eTemplateArgumentKindType); 502 EXPECT_EQ(m_ast->GetTypeTemplateArgument(t.GetOpaqueQualType(), 0), 503 int_type); 504 EXPECT_EQ(llvm::None, 505 m_ast->GetIntegralTemplateArgument(t.GetOpaqueQualType(), 0)); 506 507 EXPECT_EQ(m_ast->GetTemplateArgumentKind(t.GetOpaqueQualType(), 1), 508 eTemplateArgumentKindIntegral); 509 EXPECT_EQ(m_ast->GetTypeTemplateArgument(t.GetOpaqueQualType(), 1), 510 CompilerType()); 511 auto result = m_ast->GetIntegralTemplateArgument(t.GetOpaqueQualType(), 1); 512 ASSERT_NE(llvm::None, result); 513 EXPECT_EQ(arg, result->value); 514 EXPECT_EQ(int_type, result->type); 515 } 516 } 517 518 class TestCreateClassTemplateDecl : public TestTypeSystemClang { 519 protected: 520 /// The class templates created so far by the Expect* functions below. 521 llvm::DenseSet<ClassTemplateDecl *> m_created_templates; 522 523 /// Utility function for creating a class template. 524 ClassTemplateDecl * 525 CreateClassTemplate(const TypeSystemClang::TemplateParameterInfos &infos) { 526 ClassTemplateDecl *decl = m_ast->CreateClassTemplateDecl( 527 m_ast->GetTranslationUnitDecl(), OptionalClangModuleID(), eAccessPublic, 528 "foo", TTK_Struct, infos); 529 return decl; 530 } 531 532 /// Creates a new class template with the given template parameters. 533 /// Asserts that a new ClassTemplateDecl is created. 534 /// \param description The gtest scope string that should describe the input. 535 /// \param infos The template parameters that the class template should have. 536 /// \returns The created ClassTemplateDecl. 537 ClassTemplateDecl * 538 ExpectNewTemplate(std::string description, 539 const TypeSystemClang::TemplateParameterInfos &infos) { 540 SCOPED_TRACE(description); 541 ClassTemplateDecl *first_template = CreateClassTemplate(infos); 542 // A new template should have been created. 543 EXPECT_FALSE(m_created_templates.contains(first_template)) 544 << "Didn't create new class template but reused this existing decl:\n" 545 << ClangUtil::DumpDecl(first_template); 546 m_created_templates.insert(first_template); 547 548 // Creating a new template with the same arguments should always return 549 // the template created above. 550 ClassTemplateDecl *second_template = CreateClassTemplate(infos); 551 EXPECT_EQ(first_template, second_template) 552 << "Second attempt to create class template didn't reuse first decl:\n" 553 << ClangUtil::DumpDecl(first_template) << "\nInstead created/reused:\n" 554 << ClangUtil::DumpDecl(second_template); 555 return first_template; 556 } 557 558 /// Tries to create a new class template but asserts that an existing class 559 /// template in the current AST is reused (in contract so a new class 560 /// template being created). 561 /// \param description The gtest scope string that should describe the input. 562 /// \param infos The template parameters that the class template should have. 563 void 564 ExpectReusedTemplate(std::string description, 565 const TypeSystemClang::TemplateParameterInfos &infos, 566 ClassTemplateDecl *expected) { 567 SCOPED_TRACE(description); 568 ClassTemplateDecl *td = CreateClassTemplate(infos); 569 EXPECT_EQ(td, expected) 570 << "Created/reused class template is:\n" 571 << ClangUtil::DumpDecl(td) << "\nExpected to reuse:\n" 572 << ClangUtil::DumpDecl(expected); 573 } 574 }; 575 576 TEST_F(TestCreateClassTemplateDecl, FindExistingTemplates) { 577 // This tests the logic in TypeSystemClang::CreateClassTemplateDecl that 578 // decides whether an existing ClassTemplateDecl in the AST can be reused. 579 // The behaviour should follow the C++ rules for redeclaring templates 580 // (e.g., parameter names can be changed/omitted.) 581 582 // This describes a class template *instantiation* from which we will infer 583 // the structure of the class template. 584 TypeSystemClang::TemplateParameterInfos infos; 585 586 // Test an empty template parameter list: <> 587 ExpectNewTemplate("<>", infos); 588 589 // Test that <typename T> with T = int creates a new template. 590 infos.names = {"T"}; 591 infos.args = {TemplateArgument(m_ast->getASTContext().IntTy)}; 592 ClassTemplateDecl *single_type_arg = ExpectNewTemplate("<typename T>", infos); 593 594 // Test that changing the parameter name doesn't create a new class template. 595 infos.names = {"A"}; 596 ExpectReusedTemplate("<typename A> (A = int)", infos, single_type_arg); 597 598 // Test that changing the used type doesn't create a new class template. 599 infos.args = {TemplateArgument(m_ast->getASTContext().FloatTy)}; 600 ExpectReusedTemplate("<typename A> (A = float)", infos, single_type_arg); 601 602 // Test that <typename A, signed char I> creates a new template with A = int 603 // and I = 47; 604 infos.names.push_back("I"); 605 infos.args.push_back(TemplateArgument(m_ast->getASTContext(), 606 llvm::APSInt(llvm::APInt(8, 47)), 607 m_ast->getASTContext().SignedCharTy)); 608 ClassTemplateDecl *type_and_char_value = 609 ExpectNewTemplate("<typename A, signed char I> (I = 47)", infos); 610 611 // Change the value of the I parameter to 123. The previously created 612 // class template should still be reused. 613 infos.args.pop_back(); 614 infos.args.push_back(TemplateArgument(m_ast->getASTContext(), 615 llvm::APSInt(llvm::APInt(8, 123)), 616 m_ast->getASTContext().SignedCharTy)); 617 ExpectReusedTemplate("<typename A, signed char I> (I = 123)", infos, 618 type_and_char_value); 619 620 // Change the type of the I parameter to int so we have <typename A, int I>. 621 // The class template from above can't be reused. 622 infos.args.pop_back(); 623 infos.args.push_back(TemplateArgument(m_ast->getASTContext(), 624 llvm::APSInt(llvm::APInt(32, 47)), 625 m_ast->getASTContext().IntTy)); 626 ExpectNewTemplate("<typename A, int I> (I = 123)", infos); 627 628 // Test a second type parameter will also cause a new template to be created. 629 // We now have <typename A, int I, typename B>. 630 infos.names.push_back("B"); 631 infos.args.push_back(TemplateArgument(m_ast->getASTContext().IntTy)); 632 ClassTemplateDecl *type_and_char_value_and_type = 633 ExpectNewTemplate("<typename A, int I, typename B>", infos); 634 635 // Remove all the names from the parameters which shouldn't influence the 636 // way the templates get merged. 637 infos.names = {"", "", ""}; 638 ExpectReusedTemplate("<typename, int, typename>", infos, 639 type_and_char_value_and_type); 640 } 641 642 TEST_F(TestCreateClassTemplateDecl, FindExistingTemplatesWithParameterPack) { 643 // The same as FindExistingTemplates but for templates with parameter packs. 644 645 TypeSystemClang::TemplateParameterInfos infos; 646 infos.packed_args = 647 std::make_unique<TypeSystemClang::TemplateParameterInfos>(); 648 infos.packed_args->names = {"", ""}; 649 infos.packed_args->args = {TemplateArgument(m_ast->getASTContext().IntTy), 650 TemplateArgument(m_ast->getASTContext().IntTy)}; 651 ClassTemplateDecl *type_pack = 652 ExpectNewTemplate("<typename ...> (int, int)", infos); 653 654 // Special case: An instantiation for a parameter pack with no values fits 655 // to whatever class template we find. There isn't enough information to 656 // do an actual comparison here. 657 infos.packed_args = 658 std::make_unique<TypeSystemClang::TemplateParameterInfos>(); 659 ExpectReusedTemplate("<...> (no values in pack)", infos, type_pack); 660 661 // Change the type content of pack type values. 662 infos.packed_args->names = {"", ""}; 663 infos.packed_args->args = {TemplateArgument(m_ast->getASTContext().IntTy), 664 TemplateArgument(m_ast->getASTContext().LongTy)}; 665 ExpectReusedTemplate("<typename ...> (int, long)", infos, type_pack); 666 667 // Change the number of pack values. 668 infos.packed_args->args = {TemplateArgument(m_ast->getASTContext().IntTy)}; 669 ExpectReusedTemplate("<typename ...> (int)", infos, type_pack); 670 671 // The names of the pack values shouldn't matter. 672 infos.packed_args->names = {"A", "B"}; 673 ExpectReusedTemplate("<typename ...> (int)", infos, type_pack); 674 675 // Changing the kind of template argument will create a new template. 676 infos.packed_args->args = {TemplateArgument(m_ast->getASTContext(), 677 llvm::APSInt(llvm::APInt(32, 1)), 678 m_ast->getASTContext().IntTy)}; 679 ClassTemplateDecl *int_pack = ExpectNewTemplate("<int ...> (int = 1)", infos); 680 681 // Changing the value of integral parameters will not create a new template. 682 infos.packed_args->args = {TemplateArgument( 683 m_ast->getASTContext(), llvm::APSInt(llvm::APInt(32, 123)), 684 m_ast->getASTContext().IntTy)}; 685 ExpectReusedTemplate("<int ...> (int = 123)", infos, int_pack); 686 687 // Changing the integral type will create a new template. 688 infos.packed_args->args = {TemplateArgument(m_ast->getASTContext(), 689 llvm::APSInt(llvm::APInt(64, 1)), 690 m_ast->getASTContext().LongTy)}; 691 ExpectNewTemplate("<long ...> (long = 1)", infos); 692 693 // Prependinding a non-pack parameter will create a new template. 694 infos.names = {"T"}; 695 infos.args = {TemplateArgument(m_ast->getASTContext().IntTy)}; 696 ExpectNewTemplate("<typename T, long...> (T = int, long = 1)", infos); 697 } 698 699 TEST_F(TestTypeSystemClang, OnlyPackName) { 700 TypeSystemClang::TemplateParameterInfos infos; 701 infos.pack_name = "A"; 702 EXPECT_FALSE(infos.IsValid()); 703 } 704 705 static QualType makeConstInt(clang::ASTContext &ctxt) { 706 QualType result(ctxt.IntTy); 707 result.addConst(); 708 return result; 709 } 710 711 TEST_F(TestTypeSystemClang, TestGetTypeClassDeclType) { 712 clang::ASTContext &ctxt = m_ast->getASTContext(); 713 auto *nullptr_expr = new (ctxt) CXXNullPtrLiteralExpr(ctxt.NullPtrTy, SourceLocation()); 714 QualType t = ctxt.getDecltypeType(nullptr_expr, makeConstInt(ctxt)); 715 EXPECT_EQ(lldb::eTypeClassBuiltin, m_ast->GetTypeClass(t.getAsOpaquePtr())); 716 } 717 718 TEST_F(TestTypeSystemClang, TestGetTypeClassTypeOf) { 719 clang::ASTContext &ctxt = m_ast->getASTContext(); 720 QualType t = ctxt.getTypeOfType(makeConstInt(ctxt)); 721 EXPECT_EQ(lldb::eTypeClassBuiltin, m_ast->GetTypeClass(t.getAsOpaquePtr())); 722 } 723 724 TEST_F(TestTypeSystemClang, TestGetTypeClassTypeOfExpr) { 725 clang::ASTContext &ctxt = m_ast->getASTContext(); 726 auto *nullptr_expr = new (ctxt) CXXNullPtrLiteralExpr(ctxt.NullPtrTy, SourceLocation()); 727 QualType t = ctxt.getTypeOfExprType(nullptr_expr); 728 EXPECT_EQ(lldb::eTypeClassBuiltin, m_ast->GetTypeClass(t.getAsOpaquePtr())); 729 } 730 731 TEST_F(TestTypeSystemClang, TestGetTypeClassNested) { 732 clang::ASTContext &ctxt = m_ast->getASTContext(); 733 QualType t_base = ctxt.getTypeOfType(makeConstInt(ctxt)); 734 QualType t = ctxt.getTypeOfType(t_base); 735 EXPECT_EQ(lldb::eTypeClassBuiltin, m_ast->GetTypeClass(t.getAsOpaquePtr())); 736 } 737 738 TEST_F(TestTypeSystemClang, TestFunctionTemplateConstruction) { 739 // Tests creating a function template. 740 741 CompilerType int_type = m_ast->GetBasicType(lldb::eBasicTypeInt); 742 clang::TranslationUnitDecl *TU = m_ast->GetTranslationUnitDecl(); 743 744 // Prepare the declarations/types we need for the template. 745 CompilerType clang_type = 746 m_ast->CreateFunctionType(int_type, nullptr, 0U, false, 0U); 747 FunctionDecl *func = m_ast->CreateFunctionDeclaration( 748 TU, OptionalClangModuleID(), "foo", clang_type, StorageClass::SC_None, 749 false); 750 TypeSystemClang::TemplateParameterInfos empty_params; 751 752 // Create the actual function template. 753 clang::FunctionTemplateDecl *func_template = 754 m_ast->CreateFunctionTemplateDecl(TU, OptionalClangModuleID(), func, 755 empty_params); 756 757 EXPECT_EQ(TU, func_template->getDeclContext()); 758 EXPECT_EQ("foo", func_template->getName()); 759 EXPECT_EQ(clang::AccessSpecifier::AS_none, func_template->getAccess()); 760 } 761 762 TEST_F(TestTypeSystemClang, TestFunctionTemplateInRecordConstruction) { 763 // Tests creating a function template inside a record. 764 765 CompilerType int_type = m_ast->GetBasicType(lldb::eBasicTypeInt); 766 clang::TranslationUnitDecl *TU = m_ast->GetTranslationUnitDecl(); 767 768 // Create a record we can put the function template int. 769 CompilerType record_type = 770 clang_utils::createRecordWithField(*m_ast, "record", int_type, "field"); 771 clang::TagDecl *record = ClangUtil::GetAsTagDecl(record_type); 772 773 // Prepare the declarations/types we need for the template. 774 CompilerType clang_type = 775 m_ast->CreateFunctionType(int_type, nullptr, 0U, false, 0U); 776 // We create the FunctionDecl for the template in the TU DeclContext because: 777 // 1. FunctionDecls can't be in a Record (only CXXMethodDecls can). 778 // 2. It is mirroring the behavior of DWARFASTParserClang::ParseSubroutine. 779 FunctionDecl *func = m_ast->CreateFunctionDeclaration( 780 TU, OptionalClangModuleID(), "foo", clang_type, StorageClass::SC_None, 781 false); 782 TypeSystemClang::TemplateParameterInfos empty_params; 783 784 // Create the actual function template. 785 clang::FunctionTemplateDecl *func_template = 786 m_ast->CreateFunctionTemplateDecl(record, OptionalClangModuleID(), func, 787 empty_params); 788 789 EXPECT_EQ(record, func_template->getDeclContext()); 790 EXPECT_EQ("foo", func_template->getName()); 791 EXPECT_EQ(clang::AccessSpecifier::AS_public, func_template->getAccess()); 792 } 793 794 TEST_F(TestTypeSystemClang, TestDeletingImplicitCopyCstrDueToMoveCStr) { 795 // We need to simulate this behavior in our AST that we construct as we don't 796 // have a Sema instance that can do this for us: 797 // C++11 [class.copy]p7, p18: 798 // If the class definition declares a move constructor or move assignment 799 // operator, an implicitly declared copy constructor or copy assignment 800 // operator is defined as deleted. 801 802 // Create a record and start defining it. 803 llvm::StringRef class_name = "S"; 804 CompilerType t = clang_utils::createRecord(*m_ast, class_name); 805 m_ast->StartTagDeclarationDefinition(t); 806 807 // Create a move constructor that will delete the implicit copy constructor. 808 CompilerType return_type = m_ast->GetBasicType(lldb::eBasicTypeVoid); 809 CompilerType param_type = t.GetRValueReferenceType(); 810 CompilerType function_type = 811 m_ast->CreateFunctionType(return_type, ¶m_type, /*num_params*/ 1, 812 /*variadic=*/false, /*quals*/ 0U); 813 bool is_virtual = false; 814 bool is_static = false; 815 bool is_inline = false; 816 bool is_explicit = true; 817 bool is_attr_used = false; 818 bool is_artificial = false; 819 m_ast->AddMethodToCXXRecordType( 820 t.GetOpaqueQualType(), class_name, nullptr, function_type, 821 lldb::AccessType::eAccessPublic, is_virtual, is_static, is_inline, 822 is_explicit, is_attr_used, is_artificial); 823 824 // Complete the definition and check the created record. 825 m_ast->CompleteTagDeclarationDefinition(t); 826 auto *record = llvm::cast<CXXRecordDecl>(ClangUtil::GetAsTagDecl(t)); 827 // We can't call defaultedCopyConstructorIsDeleted() as this requires that 828 // the Decl passes through Sema which will actually compute this field. 829 // Instead we check that there is no copy constructor declared by the user 830 // which only leaves a non-deleted defaulted copy constructor as an option 831 // that our record will have no simple copy constructor. 832 EXPECT_FALSE(record->hasUserDeclaredCopyConstructor()); 833 EXPECT_FALSE(record->hasSimpleCopyConstructor()); 834 } 835 836 TEST_F(TestTypeSystemClang, TestNotDeletingUserCopyCstrDueToMoveCStr) { 837 // Tests that we don't delete the a user-defined copy constructor when 838 // a move constructor is provided. 839 // See also the TestDeletingImplicitCopyCstrDueToMoveCStr test. 840 llvm::StringRef class_name = "S"; 841 CompilerType t = clang_utils::createRecord(*m_ast, class_name); 842 m_ast->StartTagDeclarationDefinition(t); 843 844 CompilerType return_type = m_ast->GetBasicType(lldb::eBasicTypeVoid); 845 bool is_virtual = false; 846 bool is_static = false; 847 bool is_inline = false; 848 bool is_explicit = true; 849 bool is_attr_used = false; 850 bool is_artificial = false; 851 // Create a move constructor. 852 { 853 CompilerType param_type = t.GetRValueReferenceType(); 854 CompilerType function_type = 855 m_ast->CreateFunctionType(return_type, ¶m_type, /*num_params*/ 1, 856 /*variadic=*/false, /*quals*/ 0U); 857 m_ast->AddMethodToCXXRecordType( 858 t.GetOpaqueQualType(), class_name, nullptr, function_type, 859 lldb::AccessType::eAccessPublic, is_virtual, is_static, is_inline, 860 is_explicit, is_attr_used, is_artificial); 861 } 862 // Create a copy constructor. 863 { 864 CompilerType param_type = t.GetLValueReferenceType().AddConstModifier(); 865 CompilerType function_type = 866 m_ast->CreateFunctionType(return_type, ¶m_type, /*num_params*/ 1, 867 /*variadic=*/false, /*quals*/ 0U); 868 m_ast->AddMethodToCXXRecordType( 869 t.GetOpaqueQualType(), class_name, nullptr, function_type, 870 lldb::AccessType::eAccessPublic, is_virtual, is_static, is_inline, 871 is_explicit, is_attr_used, is_artificial); 872 } 873 874 // Complete the definition and check the created record. 875 m_ast->CompleteTagDeclarationDefinition(t); 876 auto *record = llvm::cast<CXXRecordDecl>(ClangUtil::GetAsTagDecl(t)); 877 EXPECT_TRUE(record->hasUserDeclaredCopyConstructor()); 878 } 879 880 TEST_F(TestTypeSystemClang, AddMethodToObjCObjectType) { 881 // Create an interface decl and mark it as having external storage. 882 CompilerType c = m_ast->CreateObjCClass("A", m_ast->GetTranslationUnitDecl(), 883 OptionalClangModuleID(), 884 /*IsForwardDecl*/ false, 885 /*IsInternal*/ false); 886 ObjCInterfaceDecl *interface = m_ast->GetAsObjCInterfaceDecl(c); 887 m_ast->SetHasExternalStorage(c.GetOpaqueQualType(), true); 888 EXPECT_TRUE(interface->hasExternalLexicalStorage()); 889 890 // Add a method to the interface. 891 std::vector<CompilerType> args; 892 CompilerType func_type = 893 m_ast->CreateFunctionType(m_ast->GetBasicType(lldb::eBasicTypeInt), 894 args.data(), args.size(), /*variadic*/ false, 895 /*quals*/ 0, clang::CallingConv::CC_C); 896 bool variadic = false; 897 bool artificial = false; 898 bool objc_direct = false; 899 clang::ObjCMethodDecl *method = TypeSystemClang::AddMethodToObjCObjectType( 900 c, "-[A foo]", func_type, lldb::eAccessPublic, artificial, variadic, 901 objc_direct); 902 ASSERT_NE(method, nullptr); 903 904 // The interface decl should still have external lexical storage. 905 EXPECT_TRUE(interface->hasExternalLexicalStorage()); 906 907 // Test some properties of the created ObjCMethodDecl. 908 EXPECT_FALSE(method->isVariadic()); 909 EXPECT_TRUE(method->isImplicit()); 910 EXPECT_FALSE(method->isDirectMethod()); 911 EXPECT_EQ(method->getDeclName().getObjCSelector().getAsString(), "foo"); 912 } 913 914 TEST(TestScratchTypeSystemClang, InferSubASTFromLangOpts) { 915 LangOptions lang_opts; 916 EXPECT_EQ( 917 ScratchTypeSystemClang::DefaultAST, 918 ScratchTypeSystemClang::InferIsolatedASTKindFromLangOpts(lang_opts)); 919 920 lang_opts.Modules = true; 921 EXPECT_EQ( 922 ScratchTypeSystemClang::IsolatedASTKind::CppModules, 923 ScratchTypeSystemClang::InferIsolatedASTKindFromLangOpts(lang_opts)); 924 } 925 926 TEST_F(TestTypeSystemClang, GetExeModuleWhenMissingSymbolFile) { 927 CompilerType compiler_type = m_ast->GetBasicTypeFromAST(lldb::eBasicTypeInt); 928 lldb_private::Type t(0, nullptr, ConstString("MyType"), llvm::None, nullptr, 929 0, {}, {}, compiler_type, 930 lldb_private::Type::ResolveState::Full); 931 // Test that getting the execution module when no type system is present 932 // is handled gracefully. 933 ModuleSP module = t.GetExeModule(); 934 EXPECT_EQ(module.get(), nullptr); 935 } 936 937