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 EXPECT_EQ(m_ast->GetTemplateArgumentKind(t.GetOpaqueQualType(), 0), 504 eTemplateArgumentKindType); 505 EXPECT_EQ(m_ast->GetTypeTemplateArgument(t.GetOpaqueQualType(), 0), 506 int_type); 507 EXPECT_EQ(llvm::None, 508 m_ast->GetIntegralTemplateArgument(t.GetOpaqueQualType(), 0)); 509 510 EXPECT_EQ(m_ast->GetTemplateArgumentKind(t.GetOpaqueQualType(), 1), 511 eTemplateArgumentKindIntegral); 512 EXPECT_EQ(m_ast->GetTypeTemplateArgument(t.GetOpaqueQualType(), 1), 513 CompilerType()); 514 auto result = m_ast->GetIntegralTemplateArgument(t.GetOpaqueQualType(), 1); 515 ASSERT_NE(llvm::None, result); 516 EXPECT_EQ(arg, result->value); 517 EXPECT_EQ(int_type, result->type); 518 } 519 } 520 521 class TestCreateClassTemplateDecl : public TestTypeSystemClang { 522 protected: 523 /// The class templates created so far by the Expect* functions below. 524 llvm::DenseSet<ClassTemplateDecl *> m_created_templates; 525 526 /// Utility function for creating a class template. 527 ClassTemplateDecl * 528 CreateClassTemplate(const TypeSystemClang::TemplateParameterInfos &infos) { 529 ClassTemplateDecl *decl = m_ast->CreateClassTemplateDecl( 530 m_ast->GetTranslationUnitDecl(), OptionalClangModuleID(), eAccessPublic, 531 "foo", TTK_Struct, infos); 532 return decl; 533 } 534 535 /// Creates a new class template with the given template parameters. 536 /// Asserts that a new ClassTemplateDecl is created. 537 /// \param description The gtest scope string that should describe the input. 538 /// \param infos The template parameters that the class template should have. 539 /// \returns The created ClassTemplateDecl. 540 ClassTemplateDecl * 541 ExpectNewTemplate(std::string description, 542 const TypeSystemClang::TemplateParameterInfos &infos) { 543 SCOPED_TRACE(description); 544 ClassTemplateDecl *first_template = CreateClassTemplate(infos); 545 // A new template should have been created. 546 EXPECT_FALSE(m_created_templates.contains(first_template)) 547 << "Didn't create new class template but reused this existing decl:\n" 548 << ClangUtil::DumpDecl(first_template); 549 m_created_templates.insert(first_template); 550 551 // Creating a new template with the same arguments should always return 552 // the template created above. 553 ClassTemplateDecl *second_template = CreateClassTemplate(infos); 554 EXPECT_EQ(first_template, second_template) 555 << "Second attempt to create class template didn't reuse first decl:\n" 556 << ClangUtil::DumpDecl(first_template) << "\nInstead created/reused:\n" 557 << ClangUtil::DumpDecl(second_template); 558 return first_template; 559 } 560 561 /// Tries to create a new class template but asserts that an existing class 562 /// template in the current AST is reused (in contract so a new class 563 /// template being created). 564 /// \param description The gtest scope string that should describe the input. 565 /// \param infos The template parameters that the class template should have. 566 void 567 ExpectReusedTemplate(std::string description, 568 const TypeSystemClang::TemplateParameterInfos &infos, 569 ClassTemplateDecl *expected) { 570 SCOPED_TRACE(description); 571 ClassTemplateDecl *td = CreateClassTemplate(infos); 572 EXPECT_EQ(td, expected) 573 << "Created/reused class template is:\n" 574 << ClangUtil::DumpDecl(td) << "\nExpected to reuse:\n" 575 << ClangUtil::DumpDecl(expected); 576 } 577 }; 578 579 TEST_F(TestCreateClassTemplateDecl, FindExistingTemplates) { 580 // This tests the logic in TypeSystemClang::CreateClassTemplateDecl that 581 // decides whether an existing ClassTemplateDecl in the AST can be reused. 582 // The behaviour should follow the C++ rules for redeclaring templates 583 // (e.g., parameter names can be changed/omitted.) 584 585 // This describes a class template *instantiation* from which we will infer 586 // the structure of the class template. 587 TypeSystemClang::TemplateParameterInfos infos; 588 589 // Test an empty template parameter list: <> 590 ExpectNewTemplate("<>", infos); 591 592 // Test that <typename T> with T = int creates a new template. 593 infos.names = {"T"}; 594 infos.args = {TemplateArgument(m_ast->getASTContext().IntTy)}; 595 ClassTemplateDecl *single_type_arg = ExpectNewTemplate("<typename T>", infos); 596 597 // Test that changing the parameter name doesn't create a new class template. 598 infos.names = {"A"}; 599 ExpectReusedTemplate("<typename A> (A = int)", infos, single_type_arg); 600 601 // Test that changing the used type doesn't create a new class template. 602 infos.args = {TemplateArgument(m_ast->getASTContext().FloatTy)}; 603 ExpectReusedTemplate("<typename A> (A = float)", infos, single_type_arg); 604 605 // Test that <typename A, signed char I> creates a new template with A = int 606 // and I = 47; 607 infos.names.push_back("I"); 608 infos.args.push_back(TemplateArgument(m_ast->getASTContext(), 609 llvm::APSInt(llvm::APInt(8, 47)), 610 m_ast->getASTContext().SignedCharTy)); 611 ClassTemplateDecl *type_and_char_value = 612 ExpectNewTemplate("<typename A, signed char I> (I = 47)", infos); 613 614 // Change the value of the I parameter to 123. The previously created 615 // class template should still be reused. 616 infos.args.pop_back(); 617 infos.args.push_back(TemplateArgument(m_ast->getASTContext(), 618 llvm::APSInt(llvm::APInt(8, 123)), 619 m_ast->getASTContext().SignedCharTy)); 620 ExpectReusedTemplate("<typename A, signed char I> (I = 123)", infos, 621 type_and_char_value); 622 623 // Change the type of the I parameter to int so we have <typename A, int I>. 624 // The class template from above can't be reused. 625 infos.args.pop_back(); 626 infos.args.push_back(TemplateArgument(m_ast->getASTContext(), 627 llvm::APSInt(llvm::APInt(32, 47)), 628 m_ast->getASTContext().IntTy)); 629 ExpectNewTemplate("<typename A, int I> (I = 123)", infos); 630 631 // Test a second type parameter will also cause a new template to be created. 632 // We now have <typename A, int I, typename B>. 633 infos.names.push_back("B"); 634 infos.args.push_back(TemplateArgument(m_ast->getASTContext().IntTy)); 635 ClassTemplateDecl *type_and_char_value_and_type = 636 ExpectNewTemplate("<typename A, int I, typename B>", infos); 637 638 // Remove all the names from the parameters which shouldn't influence the 639 // way the templates get merged. 640 infos.names = {"", "", ""}; 641 ExpectReusedTemplate("<typename, int, typename>", infos, 642 type_and_char_value_and_type); 643 } 644 645 TEST_F(TestCreateClassTemplateDecl, FindExistingTemplatesWithParameterPack) { 646 // The same as FindExistingTemplates but for templates with parameter packs. 647 648 TypeSystemClang::TemplateParameterInfos infos; 649 infos.packed_args = 650 std::make_unique<TypeSystemClang::TemplateParameterInfos>(); 651 infos.packed_args->names = {"", ""}; 652 infos.packed_args->args = {TemplateArgument(m_ast->getASTContext().IntTy), 653 TemplateArgument(m_ast->getASTContext().IntTy)}; 654 ClassTemplateDecl *type_pack = 655 ExpectNewTemplate("<typename ...> (int, int)", infos); 656 657 // Special case: An instantiation for a parameter pack with no values fits 658 // to whatever class template we find. There isn't enough information to 659 // do an actual comparison here. 660 infos.packed_args = 661 std::make_unique<TypeSystemClang::TemplateParameterInfos>(); 662 ExpectReusedTemplate("<...> (no values in pack)", infos, type_pack); 663 664 // Change the type content of pack type values. 665 infos.packed_args->names = {"", ""}; 666 infos.packed_args->args = {TemplateArgument(m_ast->getASTContext().IntTy), 667 TemplateArgument(m_ast->getASTContext().LongTy)}; 668 ExpectReusedTemplate("<typename ...> (int, long)", infos, type_pack); 669 670 // Change the number of pack values. 671 infos.packed_args->args = {TemplateArgument(m_ast->getASTContext().IntTy)}; 672 ExpectReusedTemplate("<typename ...> (int)", infos, type_pack); 673 674 // The names of the pack values shouldn't matter. 675 infos.packed_args->names = {"A", "B"}; 676 ExpectReusedTemplate("<typename ...> (int)", infos, type_pack); 677 678 // Changing the kind of template argument will create a new template. 679 infos.packed_args->args = {TemplateArgument(m_ast->getASTContext(), 680 llvm::APSInt(llvm::APInt(32, 1)), 681 m_ast->getASTContext().IntTy)}; 682 ClassTemplateDecl *int_pack = ExpectNewTemplate("<int ...> (int = 1)", infos); 683 684 // Changing the value of integral parameters will not create a new template. 685 infos.packed_args->args = {TemplateArgument( 686 m_ast->getASTContext(), llvm::APSInt(llvm::APInt(32, 123)), 687 m_ast->getASTContext().IntTy)}; 688 ExpectReusedTemplate("<int ...> (int = 123)", infos, int_pack); 689 690 // Changing the integral type will create a new template. 691 infos.packed_args->args = {TemplateArgument(m_ast->getASTContext(), 692 llvm::APSInt(llvm::APInt(64, 1)), 693 m_ast->getASTContext().LongTy)}; 694 ExpectNewTemplate("<long ...> (long = 1)", infos); 695 696 // Prependinding a non-pack parameter will create a new template. 697 infos.names = {"T"}; 698 infos.args = {TemplateArgument(m_ast->getASTContext().IntTy)}; 699 ExpectNewTemplate("<typename T, long...> (T = int, long = 1)", infos); 700 } 701 702 TEST_F(TestTypeSystemClang, OnlyPackName) { 703 TypeSystemClang::TemplateParameterInfos infos; 704 infos.pack_name = "A"; 705 EXPECT_FALSE(infos.IsValid()); 706 } 707 708 static QualType makeConstInt(clang::ASTContext &ctxt) { 709 QualType result(ctxt.IntTy); 710 result.addConst(); 711 return result; 712 } 713 714 TEST_F(TestTypeSystemClang, TestGetTypeClassDeclType) { 715 clang::ASTContext &ctxt = m_ast->getASTContext(); 716 auto *nullptr_expr = new (ctxt) CXXNullPtrLiteralExpr(ctxt.NullPtrTy, SourceLocation()); 717 QualType t = ctxt.getDecltypeType(nullptr_expr, makeConstInt(ctxt)); 718 EXPECT_EQ(lldb::eTypeClassBuiltin, m_ast->GetTypeClass(t.getAsOpaquePtr())); 719 } 720 721 TEST_F(TestTypeSystemClang, TestGetTypeClassTypeOf) { 722 clang::ASTContext &ctxt = m_ast->getASTContext(); 723 QualType t = ctxt.getTypeOfType(makeConstInt(ctxt)); 724 EXPECT_EQ(lldb::eTypeClassBuiltin, m_ast->GetTypeClass(t.getAsOpaquePtr())); 725 } 726 727 TEST_F(TestTypeSystemClang, TestGetTypeClassTypeOfExpr) { 728 clang::ASTContext &ctxt = m_ast->getASTContext(); 729 auto *nullptr_expr = new (ctxt) CXXNullPtrLiteralExpr(ctxt.NullPtrTy, SourceLocation()); 730 QualType t = ctxt.getTypeOfExprType(nullptr_expr); 731 EXPECT_EQ(lldb::eTypeClassBuiltin, m_ast->GetTypeClass(t.getAsOpaquePtr())); 732 } 733 734 TEST_F(TestTypeSystemClang, TestGetTypeClassNested) { 735 clang::ASTContext &ctxt = m_ast->getASTContext(); 736 QualType t_base = ctxt.getTypeOfType(makeConstInt(ctxt)); 737 QualType t = ctxt.getTypeOfType(t_base); 738 EXPECT_EQ(lldb::eTypeClassBuiltin, m_ast->GetTypeClass(t.getAsOpaquePtr())); 739 } 740 741 TEST_F(TestTypeSystemClang, TestFunctionTemplateConstruction) { 742 // Tests creating a function template. 743 744 CompilerType int_type = m_ast->GetBasicType(lldb::eBasicTypeInt); 745 clang::TranslationUnitDecl *TU = m_ast->GetTranslationUnitDecl(); 746 747 // Prepare the declarations/types we need for the template. 748 CompilerType clang_type = 749 m_ast->CreateFunctionType(int_type, nullptr, 0U, false, 0U); 750 FunctionDecl *func = m_ast->CreateFunctionDeclaration( 751 TU, OptionalClangModuleID(), "foo", clang_type, StorageClass::SC_None, 752 false); 753 TypeSystemClang::TemplateParameterInfos empty_params; 754 755 // Create the actual function template. 756 clang::FunctionTemplateDecl *func_template = 757 m_ast->CreateFunctionTemplateDecl(TU, OptionalClangModuleID(), func, 758 empty_params); 759 760 EXPECT_EQ(TU, func_template->getDeclContext()); 761 EXPECT_EQ("foo", func_template->getName()); 762 EXPECT_EQ(clang::AccessSpecifier::AS_none, func_template->getAccess()); 763 } 764 765 TEST_F(TestTypeSystemClang, TestFunctionTemplateInRecordConstruction) { 766 // Tests creating a function template inside a record. 767 768 CompilerType int_type = m_ast->GetBasicType(lldb::eBasicTypeInt); 769 clang::TranslationUnitDecl *TU = m_ast->GetTranslationUnitDecl(); 770 771 // Create a record we can put the function template int. 772 CompilerType record_type = 773 clang_utils::createRecordWithField(*m_ast, "record", int_type, "field"); 774 clang::TagDecl *record = ClangUtil::GetAsTagDecl(record_type); 775 776 // Prepare the declarations/types we need for the template. 777 CompilerType clang_type = 778 m_ast->CreateFunctionType(int_type, nullptr, 0U, false, 0U); 779 // We create the FunctionDecl for the template in the TU DeclContext because: 780 // 1. FunctionDecls can't be in a Record (only CXXMethodDecls can). 781 // 2. It is mirroring the behavior of DWARFASTParserClang::ParseSubroutine. 782 FunctionDecl *func = m_ast->CreateFunctionDeclaration( 783 TU, OptionalClangModuleID(), "foo", clang_type, StorageClass::SC_None, 784 false); 785 TypeSystemClang::TemplateParameterInfos empty_params; 786 787 // Create the actual function template. 788 clang::FunctionTemplateDecl *func_template = 789 m_ast->CreateFunctionTemplateDecl(record, OptionalClangModuleID(), func, 790 empty_params); 791 792 EXPECT_EQ(record, func_template->getDeclContext()); 793 EXPECT_EQ("foo", func_template->getName()); 794 EXPECT_EQ(clang::AccessSpecifier::AS_public, func_template->getAccess()); 795 } 796 797 TEST_F(TestTypeSystemClang, TestDeletingImplicitCopyCstrDueToMoveCStr) { 798 // We need to simulate this behavior in our AST that we construct as we don't 799 // have a Sema instance that can do this for us: 800 // C++11 [class.copy]p7, p18: 801 // If the class definition declares a move constructor or move assignment 802 // operator, an implicitly declared copy constructor or copy assignment 803 // operator is defined as deleted. 804 805 // Create a record and start defining it. 806 llvm::StringRef class_name = "S"; 807 CompilerType t = clang_utils::createRecord(*m_ast, class_name); 808 m_ast->StartTagDeclarationDefinition(t); 809 810 // Create a move constructor that will delete the implicit copy constructor. 811 CompilerType return_type = m_ast->GetBasicType(lldb::eBasicTypeVoid); 812 CompilerType param_type = t.GetRValueReferenceType(); 813 CompilerType function_type = 814 m_ast->CreateFunctionType(return_type, ¶m_type, /*num_params*/ 1, 815 /*variadic=*/false, /*quals*/ 0U); 816 bool is_virtual = false; 817 bool is_static = false; 818 bool is_inline = false; 819 bool is_explicit = true; 820 bool is_attr_used = false; 821 bool is_artificial = false; 822 m_ast->AddMethodToCXXRecordType( 823 t.GetOpaqueQualType(), class_name, nullptr, function_type, 824 lldb::AccessType::eAccessPublic, is_virtual, is_static, is_inline, 825 is_explicit, is_attr_used, is_artificial); 826 827 // Complete the definition and check the created record. 828 m_ast->CompleteTagDeclarationDefinition(t); 829 auto *record = llvm::cast<CXXRecordDecl>(ClangUtil::GetAsTagDecl(t)); 830 // We can't call defaultedCopyConstructorIsDeleted() as this requires that 831 // the Decl passes through Sema which will actually compute this field. 832 // Instead we check that there is no copy constructor declared by the user 833 // which only leaves a non-deleted defaulted copy constructor as an option 834 // that our record will have no simple copy constructor. 835 EXPECT_FALSE(record->hasUserDeclaredCopyConstructor()); 836 EXPECT_FALSE(record->hasSimpleCopyConstructor()); 837 } 838 839 TEST_F(TestTypeSystemClang, TestNotDeletingUserCopyCstrDueToMoveCStr) { 840 // Tests that we don't delete the a user-defined copy constructor when 841 // a move constructor is provided. 842 // See also the TestDeletingImplicitCopyCstrDueToMoveCStr test. 843 llvm::StringRef class_name = "S"; 844 CompilerType t = clang_utils::createRecord(*m_ast, class_name); 845 m_ast->StartTagDeclarationDefinition(t); 846 847 CompilerType return_type = m_ast->GetBasicType(lldb::eBasicTypeVoid); 848 bool is_virtual = false; 849 bool is_static = false; 850 bool is_inline = false; 851 bool is_explicit = true; 852 bool is_attr_used = false; 853 bool is_artificial = false; 854 // Create a move constructor. 855 { 856 CompilerType param_type = t.GetRValueReferenceType(); 857 CompilerType function_type = 858 m_ast->CreateFunctionType(return_type, ¶m_type, /*num_params*/ 1, 859 /*variadic=*/false, /*quals*/ 0U); 860 m_ast->AddMethodToCXXRecordType( 861 t.GetOpaqueQualType(), class_name, nullptr, function_type, 862 lldb::AccessType::eAccessPublic, is_virtual, is_static, is_inline, 863 is_explicit, is_attr_used, is_artificial); 864 } 865 // Create a copy constructor. 866 { 867 CompilerType param_type = t.GetLValueReferenceType().AddConstModifier(); 868 CompilerType function_type = 869 m_ast->CreateFunctionType(return_type, ¶m_type, /*num_params*/ 1, 870 /*variadic=*/false, /*quals*/ 0U); 871 m_ast->AddMethodToCXXRecordType( 872 t.GetOpaqueQualType(), class_name, nullptr, function_type, 873 lldb::AccessType::eAccessPublic, is_virtual, is_static, is_inline, 874 is_explicit, is_attr_used, is_artificial); 875 } 876 877 // Complete the definition and check the created record. 878 m_ast->CompleteTagDeclarationDefinition(t); 879 auto *record = llvm::cast<CXXRecordDecl>(ClangUtil::GetAsTagDecl(t)); 880 EXPECT_TRUE(record->hasUserDeclaredCopyConstructor()); 881 } 882 883 TEST_F(TestTypeSystemClang, AddMethodToObjCObjectType) { 884 // Create an interface decl and mark it as having external storage. 885 CompilerType c = m_ast->CreateObjCClass("A", m_ast->GetTranslationUnitDecl(), 886 OptionalClangModuleID(), 887 /*IsForwardDecl*/ false, 888 /*IsInternal*/ false); 889 ObjCInterfaceDecl *interface = m_ast->GetAsObjCInterfaceDecl(c); 890 m_ast->SetHasExternalStorage(c.GetOpaqueQualType(), true); 891 EXPECT_TRUE(interface->hasExternalLexicalStorage()); 892 893 // Add a method to the interface. 894 std::vector<CompilerType> args; 895 CompilerType func_type = 896 m_ast->CreateFunctionType(m_ast->GetBasicType(lldb::eBasicTypeInt), 897 args.data(), args.size(), /*variadic*/ false, 898 /*quals*/ 0, clang::CallingConv::CC_C); 899 bool variadic = false; 900 bool artificial = false; 901 bool objc_direct = false; 902 clang::ObjCMethodDecl *method = TypeSystemClang::AddMethodToObjCObjectType( 903 c, "-[A foo]", func_type, lldb::eAccessPublic, artificial, variadic, 904 objc_direct); 905 ASSERT_NE(method, nullptr); 906 907 // The interface decl should still have external lexical storage. 908 EXPECT_TRUE(interface->hasExternalLexicalStorage()); 909 910 // Test some properties of the created ObjCMethodDecl. 911 EXPECT_FALSE(method->isVariadic()); 912 EXPECT_TRUE(method->isImplicit()); 913 EXPECT_FALSE(method->isDirectMethod()); 914 EXPECT_EQ(method->getDeclName().getObjCSelector().getAsString(), "foo"); 915 } 916 917 TEST_F(TestTypeSystemClang, GetFullyUnqualifiedType) { 918 CompilerType bool_ = m_ast->GetBasicType(eBasicTypeBool); 919 CompilerType cv_bool = bool_.AddConstModifier().AddVolatileModifier(); 920 921 // const volatile bool -> bool 922 EXPECT_EQ(bool_, cv_bool.GetFullyUnqualifiedType()); 923 924 // const volatile bool[47] -> bool[47] 925 EXPECT_EQ(bool_.GetArrayType(47), 926 cv_bool.GetArrayType(47).GetFullyUnqualifiedType()); 927 928 // const volatile bool[47][42] -> bool[47][42] 929 EXPECT_EQ( 930 bool_.GetArrayType(42).GetArrayType(47), 931 cv_bool.GetArrayType(42).GetArrayType(47).GetFullyUnqualifiedType()); 932 933 // const volatile bool * -> bool * 934 EXPECT_EQ(bool_.GetPointerType(), 935 cv_bool.GetPointerType().GetFullyUnqualifiedType()); 936 937 // const volatile bool *[47] -> bool *[47] 938 EXPECT_EQ( 939 bool_.GetPointerType().GetArrayType(47), 940 cv_bool.GetPointerType().GetArrayType(47).GetFullyUnqualifiedType()); 941 } 942 943 TEST(TestScratchTypeSystemClang, InferSubASTFromLangOpts) { 944 LangOptions lang_opts; 945 EXPECT_EQ( 946 ScratchTypeSystemClang::DefaultAST, 947 ScratchTypeSystemClang::InferIsolatedASTKindFromLangOpts(lang_opts)); 948 949 lang_opts.Modules = true; 950 EXPECT_EQ( 951 ScratchTypeSystemClang::IsolatedASTKind::CppModules, 952 ScratchTypeSystemClang::InferIsolatedASTKindFromLangOpts(lang_opts)); 953 } 954 955 TEST_F(TestTypeSystemClang, GetExeModuleWhenMissingSymbolFile) { 956 CompilerType compiler_type = m_ast->GetBasicTypeFromAST(lldb::eBasicTypeInt); 957 lldb_private::Type t(0, nullptr, ConstString("MyType"), llvm::None, nullptr, 958 0, {}, {}, compiler_type, 959 lldb_private::Type::ResolveState::Full); 960 // Test that getting the execution module when no type system is present 961 // is handled gracefully. 962 ModuleSP module = t.GetExeModule(); 963 EXPECT_EQ(module.get(), nullptr); 964 } 965 966