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