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