brintos

brintos / llvm-project-archived public Read only

0
0
Text · 58.9 KiB · 155fc74 Raw
1367 lines · cpp
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-exception6//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 "llvm/IR/GlobalValue.h"21#include "gtest/gtest.h"22 23using namespace clang;24using namespace lldb;25using namespace lldb_private;26 27class TestTypeSystemClang : public testing::Test {28public:29  SubsystemRAII<FileSystem, HostInfo> subsystems;30 31  void SetUp() override {32    m_holder =33        std::make_unique<clang_utils::TypeSystemClangHolder>("test ASTContext");34    m_ast = m_holder->GetAST();35  }36 37  void TearDown() override {38    m_ast = nullptr;39    m_holder.reset();40  }41 42protected:43  44  TypeSystemClang *m_ast = nullptr;45  std::unique_ptr<clang_utils::TypeSystemClangHolder> m_holder;46 47  QualType GetBasicQualType(BasicType type) const {48    return ClangUtil::GetQualType(m_ast->GetBasicTypeFromAST(type));49  }50 51  QualType GetBasicQualType(const char *name) const {52    return ClangUtil::GetQualType(53        m_ast->GetBuiltinTypeByName(ConstString(name)));54  }55 56  CompilerType GetBuiltinTypeForDWARFEncodingAndBitSize(57      llvm::StringRef type_name, uint32_t encoding, uint32_t bit_size) const {58    return m_ast->GetBuiltinTypeForDWARFEncodingAndBitSize(type_name, encoding,59                                                           bit_size);60  }61};62 63TEST_F(TestTypeSystemClang, TestGetBasicTypeFromEnum) {64  clang::ASTContext &context = m_ast->getASTContext();65 66  EXPECT_TRUE(67      context.hasSameType(GetBasicQualType(eBasicTypeBool), context.BoolTy));68  EXPECT_TRUE(69      context.hasSameType(GetBasicQualType(eBasicTypeChar), context.CharTy));70  EXPECT_TRUE(context.hasSameType(GetBasicQualType(eBasicTypeChar8),71                                  context.Char8Ty));72  EXPECT_TRUE(context.hasSameType(GetBasicQualType(eBasicTypeChar16),73                                  context.Char16Ty));74  EXPECT_TRUE(context.hasSameType(GetBasicQualType(eBasicTypeChar32),75                                  context.Char32Ty));76  EXPECT_TRUE(context.hasSameType(GetBasicQualType(eBasicTypeDouble),77                                  context.DoubleTy));78  EXPECT_TRUE(context.hasSameType(GetBasicQualType(eBasicTypeDoubleComplex),79                                  context.getComplexType(context.DoubleTy)));80  EXPECT_TRUE(81      context.hasSameType(GetBasicQualType(eBasicTypeFloat), context.FloatTy));82  EXPECT_TRUE(context.hasSameType(GetBasicQualType(eBasicTypeFloatComplex),83                                  context.getComplexType(context.FloatTy)));84  EXPECT_TRUE(85      context.hasSameType(GetBasicQualType(eBasicTypeHalf), context.HalfTy));86  EXPECT_TRUE(context.hasSameType(GetBasicQualType(eBasicTypeFloat128),87                                  context.Float128Ty));88  EXPECT_TRUE(89      context.hasSameType(GetBasicQualType(eBasicTypeInt), context.IntTy));90  EXPECT_TRUE(context.hasSameType(GetBasicQualType(eBasicTypeInt128),91                                  context.Int128Ty));92  EXPECT_TRUE(93      context.hasSameType(GetBasicQualType(eBasicTypeLong), context.LongTy));94  EXPECT_TRUE(context.hasSameType(GetBasicQualType(eBasicTypeLongDouble),95                                  context.LongDoubleTy));96  EXPECT_TRUE(97      context.hasSameType(GetBasicQualType(eBasicTypeLongDoubleComplex),98                          context.getComplexType(context.LongDoubleTy)));99  EXPECT_TRUE(context.hasSameType(GetBasicQualType(eBasicTypeLongLong),100                                  context.LongLongTy));101  EXPECT_TRUE(context.hasSameType(GetBasicQualType(eBasicTypeNullPtr),102                                  context.NullPtrTy));103  EXPECT_TRUE(context.hasSameType(GetBasicQualType(eBasicTypeObjCClass),104                                  context.getObjCClassType()));105  EXPECT_TRUE(context.hasSameType(GetBasicQualType(eBasicTypeObjCID),106                                  context.getObjCIdType()));107  EXPECT_TRUE(context.hasSameType(GetBasicQualType(eBasicTypeObjCSel),108                                  context.getObjCSelType()));109  EXPECT_TRUE(110      context.hasSameType(GetBasicQualType(eBasicTypeShort), context.ShortTy));111  EXPECT_TRUE(context.hasSameType(GetBasicQualType(eBasicTypeSignedChar),112                                  context.SignedCharTy));113  EXPECT_TRUE(context.hasSameType(GetBasicQualType(eBasicTypeUnsignedChar),114                                  context.UnsignedCharTy));115  EXPECT_TRUE(context.hasSameType(GetBasicQualType(eBasicTypeUnsignedInt),116                                  context.UnsignedIntTy));117  EXPECT_TRUE(context.hasSameType(GetBasicQualType(eBasicTypeUnsignedInt128),118                                  context.UnsignedInt128Ty));119  EXPECT_TRUE(context.hasSameType(GetBasicQualType(eBasicTypeUnsignedLong),120                                  context.UnsignedLongTy));121  EXPECT_TRUE(context.hasSameType(GetBasicQualType(eBasicTypeUnsignedLongLong),122                                  context.UnsignedLongLongTy));123  EXPECT_TRUE(context.hasSameType(GetBasicQualType(eBasicTypeUnsignedShort),124                                  context.UnsignedShortTy));125  EXPECT_TRUE(126      context.hasSameType(GetBasicQualType(eBasicTypeVoid), context.VoidTy));127  EXPECT_TRUE(128      context.hasSameType(GetBasicQualType(eBasicTypeWChar), context.WCharTy));129}130 131TEST_F(TestTypeSystemClang, TestGetBasicTypeFromName) {132  EXPECT_EQ(GetBasicQualType(eBasicTypeChar), GetBasicQualType("char"));133  EXPECT_EQ(GetBasicQualType(eBasicTypeSignedChar),134            GetBasicQualType("signed char"));135  EXPECT_EQ(GetBasicQualType(eBasicTypeUnsignedChar),136            GetBasicQualType("unsigned char"));137  EXPECT_EQ(GetBasicQualType(eBasicTypeWChar), GetBasicQualType("wchar_t"));138  EXPECT_EQ(GetBasicQualType(eBasicTypeSignedWChar),139            GetBasicQualType("signed wchar_t"));140  EXPECT_EQ(GetBasicQualType(eBasicTypeUnsignedWChar),141            GetBasicQualType("unsigned wchar_t"));142  EXPECT_EQ(GetBasicQualType(eBasicTypeShort), GetBasicQualType("short"));143  EXPECT_EQ(GetBasicQualType(eBasicTypeShort), GetBasicQualType("short int"));144  EXPECT_EQ(GetBasicQualType(eBasicTypeUnsignedShort),145            GetBasicQualType("unsigned short"));146  EXPECT_EQ(GetBasicQualType(eBasicTypeUnsignedShort),147            GetBasicQualType("unsigned short int"));148  EXPECT_EQ(GetBasicQualType(eBasicTypeInt), GetBasicQualType("int"));149  EXPECT_EQ(GetBasicQualType(eBasicTypeInt), GetBasicQualType("signed int"));150  EXPECT_EQ(GetBasicQualType(eBasicTypeUnsignedInt),151            GetBasicQualType("unsigned int"));152  EXPECT_EQ(GetBasicQualType(eBasicTypeUnsignedInt),153            GetBasicQualType("unsigned"));154  EXPECT_EQ(GetBasicQualType(eBasicTypeLong), GetBasicQualType("long"));155  EXPECT_EQ(GetBasicQualType(eBasicTypeLong), GetBasicQualType("long int"));156  EXPECT_EQ(GetBasicQualType(eBasicTypeUnsignedLong),157            GetBasicQualType("unsigned long"));158  EXPECT_EQ(GetBasicQualType(eBasicTypeUnsignedLong),159            GetBasicQualType("unsigned long int"));160  EXPECT_EQ(GetBasicQualType(eBasicTypeLongLong),161            GetBasicQualType("long long"));162  EXPECT_EQ(GetBasicQualType(eBasicTypeLongLong),163            GetBasicQualType("long long int"));164  EXPECT_EQ(GetBasicQualType(eBasicTypeUnsignedLongLong),165            GetBasicQualType("unsigned long long"));166  EXPECT_EQ(GetBasicQualType(eBasicTypeUnsignedLongLong),167            GetBasicQualType("unsigned long long int"));168  EXPECT_EQ(GetBasicQualType(eBasicTypeInt128), GetBasicQualType("__int128_t"));169  EXPECT_EQ(GetBasicQualType(eBasicTypeUnsignedInt128),170            GetBasicQualType("__uint128_t"));171  EXPECT_EQ(GetBasicQualType(eBasicTypeInt128), GetBasicQualType("__int128"));172  EXPECT_EQ(GetBasicQualType(eBasicTypeUnsignedInt128),173            GetBasicQualType("unsigned __int128"));174  EXPECT_EQ(GetBasicQualType(eBasicTypeVoid), GetBasicQualType("void"));175  EXPECT_EQ(GetBasicQualType(eBasicTypeBool), GetBasicQualType("bool"));176  EXPECT_EQ(GetBasicQualType(eBasicTypeFloat), GetBasicQualType("float"));177  EXPECT_EQ(GetBasicQualType(eBasicTypeDouble), GetBasicQualType("double"));178  EXPECT_EQ(GetBasicQualType(eBasicTypeLongDouble),179            GetBasicQualType("long double"));180  EXPECT_EQ(GetBasicQualType(eBasicTypeObjCID), GetBasicQualType("id"));181  EXPECT_EQ(GetBasicQualType(eBasicTypeObjCSel), GetBasicQualType("SEL"));182  EXPECT_EQ(GetBasicQualType(eBasicTypeNullPtr), GetBasicQualType("nullptr"));183}184 185void VerifyEncodingAndBitSize(TypeSystemClang &clang_context,186                              lldb::Encoding encoding, unsigned int bit_size) {187  clang::ASTContext &context = clang_context.getASTContext();188 189  CompilerType type =190      clang_context.GetBuiltinTypeForEncodingAndBitSize(encoding, bit_size);191  EXPECT_TRUE(type.IsValid());192 193  QualType qtype = ClangUtil::GetQualType(type);194  EXPECT_FALSE(qtype.isNull());195  if (qtype.isNull())196    return;197 198  uint64_t actual_size = context.getTypeSize(qtype);199  EXPECT_EQ(bit_size, actual_size);200 201  const clang::Type *type_ptr = qtype.getTypePtr();202  EXPECT_NE(nullptr, type_ptr);203  if (!type_ptr)204    return;205 206  EXPECT_TRUE(type_ptr->isBuiltinType());207  switch (encoding) {208  case eEncodingSint:209    EXPECT_TRUE(type_ptr->isSignedIntegerType());210    break;211  case eEncodingUint:212    EXPECT_TRUE(type_ptr->isUnsignedIntegerType());213    break;214  case eEncodingIEEE754:215    EXPECT_TRUE(type_ptr->isFloatingType());216    break;217  default:218    FAIL() << "Unexpected encoding";219    break;220  }221}222 223TEST_F(TestTypeSystemClang, TestBuiltinTypeForEncodingAndBitSize) {224  // Make sure we can get types of every possible size in every possible225  // encoding.226  // We can't make any guarantee about which specific type we get, because the227  // standard228  // isn't that specific.  We only need to make sure the compiler hands us some229  // type that230  // is both a builtin type and matches the requested bit size.231  VerifyEncodingAndBitSize(*m_ast, eEncodingSint, 8);232  VerifyEncodingAndBitSize(*m_ast, eEncodingSint, 16);233  VerifyEncodingAndBitSize(*m_ast, eEncodingSint, 32);234  VerifyEncodingAndBitSize(*m_ast, eEncodingSint, 64);235  VerifyEncodingAndBitSize(*m_ast, eEncodingSint, 128);236 237  VerifyEncodingAndBitSize(*m_ast, eEncodingUint, 8);238  VerifyEncodingAndBitSize(*m_ast, eEncodingUint, 16);239  VerifyEncodingAndBitSize(*m_ast, eEncodingUint, 32);240  VerifyEncodingAndBitSize(*m_ast, eEncodingUint, 64);241  VerifyEncodingAndBitSize(*m_ast, eEncodingUint, 128);242 243  VerifyEncodingAndBitSize(*m_ast, eEncodingIEEE754, 32);244  VerifyEncodingAndBitSize(*m_ast, eEncodingIEEE754, 64);245}246 247TEST_F(TestTypeSystemClang, TestGetBuiltinTypeForDWARFEncodingAndBitSize) {248  EXPECT_FALSE(GetBuiltinTypeForDWARFEncodingAndBitSize(249                   "_BitIn", llvm::dwarf::DW_ATE_signed, 2)250                   .IsValid());251  EXPECT_FALSE(GetBuiltinTypeForDWARFEncodingAndBitSize(252                   "BitInt", llvm::dwarf::DW_ATE_signed, 2)253                   .IsValid());254  EXPECT_FALSE(GetBuiltinTypeForDWARFEncodingAndBitSize(255                   "_BitInt(2)", llvm::dwarf::DW_ATE_signed_char, 2)256                   .IsValid());257  EXPECT_FALSE(GetBuiltinTypeForDWARFEncodingAndBitSize(258                   "_BitInt", llvm::dwarf::DW_ATE_signed_char, 2)259                   .IsValid());260  EXPECT_FALSE(GetBuiltinTypeForDWARFEncodingAndBitSize(261                   "_BitInt(2)", llvm::dwarf::DW_ATE_unsigned, 2)262                   .IsValid());263  EXPECT_FALSE(GetBuiltinTypeForDWARFEncodingAndBitSize(264                   "_BitInt", llvm::dwarf::DW_ATE_unsigned, 2)265                   .IsValid());266 267  EXPECT_EQ(GetBuiltinTypeForDWARFEncodingAndBitSize(268                "_BitInt(2)", llvm::dwarf::DW_ATE_signed, 2)269                .GetTypeName(),270            "_BitInt(2)");271  EXPECT_EQ(GetBuiltinTypeForDWARFEncodingAndBitSize(272                "_BitInt", llvm::dwarf::DW_ATE_signed, 2)273                .GetTypeName(),274            "_BitInt(2)");275  EXPECT_EQ(GetBuiltinTypeForDWARFEncodingAndBitSize(276                "_BitInt(129)", llvm::dwarf::DW_ATE_signed, 129)277                .GetTypeName(),278            "_BitInt(129)");279  EXPECT_EQ(GetBuiltinTypeForDWARFEncodingAndBitSize(280                "_BitInt", llvm::dwarf::DW_ATE_signed, 129)281                .GetTypeName(),282            "_BitInt(129)");283 284  EXPECT_FALSE(GetBuiltinTypeForDWARFEncodingAndBitSize(285                   "unsigned _BitIn", llvm::dwarf::DW_ATE_unsigned, 2)286                   .IsValid());287  EXPECT_FALSE(GetBuiltinTypeForDWARFEncodingAndBitSize(288                   "unsigned BitInt", llvm::dwarf::DW_ATE_unsigned, 2)289                   .IsValid());290  EXPECT_FALSE(GetBuiltinTypeForDWARFEncodingAndBitSize(291                   "unsigned _BitInt(2)", llvm::dwarf::DW_ATE_unsigned_char, 2)292                   .IsValid());293  EXPECT_FALSE(GetBuiltinTypeForDWARFEncodingAndBitSize(294                   "unsigned _BitInt", llvm::dwarf::DW_ATE_unsigned_char, 2)295                   .IsValid());296  EXPECT_FALSE(GetBuiltinTypeForDWARFEncodingAndBitSize(297                   "unsigned _BitInt(2)", llvm::dwarf::DW_ATE_signed, 2)298                   .IsValid());299  EXPECT_FALSE(GetBuiltinTypeForDWARFEncodingAndBitSize(300                   "unsigned _BitInt", llvm::dwarf::DW_ATE_signed, 2)301                   .IsValid());302 303  EXPECT_EQ(GetBuiltinTypeForDWARFEncodingAndBitSize(304                "unsigned _BitInt(2)", llvm::dwarf::DW_ATE_unsigned, 2)305                .GetTypeName(),306            "unsigned _BitInt(2)");307  EXPECT_EQ(GetBuiltinTypeForDWARFEncodingAndBitSize(308                "unsigned _BitInt", llvm::dwarf::DW_ATE_unsigned, 2)309                .GetTypeName(),310            "unsigned _BitInt(2)");311  EXPECT_EQ(GetBuiltinTypeForDWARFEncodingAndBitSize(312                "unsigned _BitInt(129)", llvm::dwarf::DW_ATE_unsigned, 129)313                .GetTypeName(),314            "unsigned _BitInt(129)");315  EXPECT_EQ(GetBuiltinTypeForDWARFEncodingAndBitSize(316                "unsigned _BitInt", llvm::dwarf::DW_ATE_unsigned, 129)317                .GetTypeName(),318            "unsigned _BitInt(129)");319}320 321TEST_F(TestTypeSystemClang, TestBitIntTypeInfo) {322  EXPECT_EQ(GetBuiltinTypeForDWARFEncodingAndBitSize(323                "_BitInt", llvm::dwarf::DW_ATE_signed, 2)324                .GetTypeInfo(),325            eTypeIsSigned | eTypeIsScalar | eTypeHasValue | eTypeIsInteger);326  EXPECT_EQ(GetBuiltinTypeForDWARFEncodingAndBitSize(327                "unsigned _BitInt", llvm::dwarf::DW_ATE_unsigned, 2)328                .GetTypeInfo(),329            eTypeIsScalar | eTypeHasValue | eTypeIsInteger);330}331 332TEST_F(TestTypeSystemClang, TestBuiltinTypeForEmptyTriple) {333  // Test that we can access type-info of builtin Clang AST334  // types without crashing even when the target triple is335  // empty.336 337  TypeSystemClang ast("empty triple AST", llvm::Triple{});338 339  // This test only makes sense if the builtin ASTContext types were340  // not initialized.341  ASSERT_TRUE(ast.getASTContext().VoidPtrTy.isNull());342 343  EXPECT_FALSE(ast.GetBuiltinTypeByName(ConstString("int")).IsValid());344  EXPECT_FALSE(ast.GetBuiltinTypeForDWARFEncodingAndBitSize(345                      "char", llvm::dwarf::DW_ATE_signed_char, 8)346                   .IsValid());347  EXPECT_FALSE(ast.GetBuiltinTypeForEncodingAndBitSize(lldb::eEncodingUint, 8)348                   .IsValid());349  EXPECT_FALSE(ast.GetPointerSizedIntType(/*is_signed=*/false));350  EXPECT_FALSE(ast.GetIntTypeFromBitSize(8, /*is_signed=*/false));351 352  CompilerType record_type = ast.CreateRecordType(353      nullptr, OptionalClangModuleID(), lldb::eAccessPublic, "Record",354      llvm::to_underlying(clang::TagTypeKind::Struct),355      lldb::eLanguageTypeC_plus_plus, std::nullopt);356  TypeSystemClang::StartTagDeclarationDefinition(record_type);357  EXPECT_EQ(ast.AddFieldToRecordType(record_type, "field", record_type,358                                     eAccessPublic, /*bitfield_bit_size=*/8),359            nullptr);360  TypeSystemClang::CompleteTagDeclarationDefinition(record_type);361}362 363TEST_F(TestTypeSystemClang, TestDisplayName) {364  TypeSystemClang ast("some name", llvm::Triple());365  EXPECT_EQ("some name", ast.getDisplayName());366}367 368TEST_F(TestTypeSystemClang, TestDisplayNameEmpty) {369  TypeSystemClang ast("", llvm::Triple());370  EXPECT_EQ("", ast.getDisplayName());371}372 373TEST_F(TestTypeSystemClang, TestGetEnumIntegerTypeInvalid) {374  EXPECT_FALSE(m_ast->GetEnumerationIntegerType(CompilerType()).IsValid());375}376 377TEST_F(TestTypeSystemClang, TestGetEnumIntegerTypeUnexpectedType) {378  CompilerType int_type = m_ast->GetBasicType(lldb::eBasicTypeInt);379  CompilerType t = m_ast->GetEnumerationIntegerType(int_type);380  EXPECT_FALSE(t.IsValid());381}382 383TEST_F(TestTypeSystemClang, TestGetEnumIntegerTypeBasicTypes) {384  // All possible underlying integer types of enums.385  const std::vector<lldb::BasicType> types_to_test = {386      eBasicTypeInt,          eBasicTypeUnsignedInt, eBasicTypeLong,387      eBasicTypeUnsignedLong, eBasicTypeLongLong,    eBasicTypeUnsignedLongLong,388  };389 390  for (bool scoped : {true, false}) {391    SCOPED_TRACE("scoped: " + std::to_string(scoped));392    for (lldb::BasicType basic_type : types_to_test) {393      SCOPED_TRACE(std::to_string(basic_type));394 395      auto holder =396          std::make_unique<clang_utils::TypeSystemClangHolder>("enum_ast");397      auto &ast = *holder->GetAST();398 399      CompilerType basic_compiler_type = ast.GetBasicType(basic_type);400      EXPECT_TRUE(basic_compiler_type.IsValid());401 402      CompilerType enum_type = ast.CreateEnumerationType(403          "my_enum", ast.GetTranslationUnitDecl(), OptionalClangModuleID(),404          Declaration(), basic_compiler_type, scoped);405 406      CompilerType t = ast.GetEnumerationIntegerType(enum_type);407      // Check that the type we put in at the start is found again.408      EXPECT_EQ(basic_compiler_type.GetTypeName(), t.GetTypeName());409    }410  }411}412 413TEST_F(TestTypeSystemClang, TestEnumerationValueSign) {414  CompilerType enum_type = m_ast->CreateEnumerationType(415      "my_enum_signed", m_ast->GetTranslationUnitDecl(),416      OptionalClangModuleID(), Declaration(),417      m_ast->GetBasicType(lldb::eBasicTypeSignedChar), false);418  auto *enum_decl = m_ast->AddEnumerationValueToEnumerationType(419      enum_type, Declaration(), "minus_one", -1, 8);420  EXPECT_TRUE(enum_decl->getInitVal().isSigned());421}422 423TEST_F(TestTypeSystemClang, TestOwningModule) {424  auto holder =425      std::make_unique<clang_utils::TypeSystemClangHolder>("module_ast");426  auto &ast = *holder->GetAST();427  CompilerType basic_compiler_type = ast.GetBasicType(BasicType::eBasicTypeInt);428  CompilerType enum_type = ast.CreateEnumerationType(429      "my_enum", ast.GetTranslationUnitDecl(), OptionalClangModuleID(100),430      Declaration(), basic_compiler_type, false);431  auto *ed = TypeSystemClang::GetAsEnumDecl(enum_type);432  EXPECT_FALSE(!ed);433  EXPECT_EQ(ed->getOwningModuleID(), 100u);434 435  CompilerType record_type = ast.CreateRecordType(436      nullptr, OptionalClangModuleID(200), lldb::eAccessPublic, "FooRecord",437      llvm::to_underlying(clang::TagTypeKind::Struct),438      lldb::eLanguageTypeC_plus_plus, std::nullopt);439  auto *rd = TypeSystemClang::GetAsRecordDecl(record_type);440  EXPECT_FALSE(!rd);441  EXPECT_EQ(rd->getOwningModuleID(), 200u);442 443  CompilerType class_type =444      ast.CreateObjCClass("objc_class", ast.GetTranslationUnitDecl(),445                          OptionalClangModuleID(300), false);446  auto *cd = TypeSystemClang::GetAsObjCInterfaceDecl(class_type);447  EXPECT_FALSE(!cd);448  EXPECT_EQ(cd->getOwningModuleID(), 300u);449}450 451TEST_F(TestTypeSystemClang, TestIsClangType) {452  clang::ASTContext &context = m_ast->getASTContext();453  lldb::opaque_compiler_type_t bool_ctype =454      TypeSystemClang::GetOpaqueCompilerType(&context, lldb::eBasicTypeBool);455  CompilerType bool_type(m_ast->weak_from_this(), bool_ctype);456  CompilerType record_type = m_ast->CreateRecordType(457      nullptr, OptionalClangModuleID(100), lldb::eAccessPublic, "FooRecord",458      llvm::to_underlying(clang::TagTypeKind::Struct),459      lldb::eLanguageTypeC_plus_plus, std::nullopt);460  // Clang builtin type and record type should pass461  EXPECT_TRUE(ClangUtil::IsClangType(bool_type));462  EXPECT_TRUE(ClangUtil::IsClangType(record_type));463 464  // Default constructed type should fail465  EXPECT_FALSE(ClangUtil::IsClangType(CompilerType()));466}467 468TEST_F(TestTypeSystemClang, TestRemoveFastQualifiers) {469  CompilerType record_type = m_ast->CreateRecordType(470      nullptr, OptionalClangModuleID(), lldb::eAccessPublic, "FooRecord",471      llvm::to_underlying(clang::TagTypeKind::Struct),472      lldb::eLanguageTypeC_plus_plus, std::nullopt);473  QualType qt;474 475  qt = ClangUtil::GetQualType(record_type);476  EXPECT_EQ(0u, qt.getLocalFastQualifiers());477  record_type = record_type.AddConstModifier();478  record_type = record_type.AddVolatileModifier();479  record_type = record_type.AddRestrictModifier();480  qt = ClangUtil::GetQualType(record_type);481  EXPECT_NE(0u, qt.getLocalFastQualifiers());482  record_type = ClangUtil::RemoveFastQualifiers(record_type);483  qt = ClangUtil::GetQualType(record_type);484  EXPECT_EQ(0u, qt.getLocalFastQualifiers());485}486 487TEST_F(TestTypeSystemClang, TestConvertAccessTypeToAccessSpecifier) {488  EXPECT_EQ(AS_none,489            TypeSystemClang::ConvertAccessTypeToAccessSpecifier(eAccessNone));490  EXPECT_EQ(AS_none, TypeSystemClang::ConvertAccessTypeToAccessSpecifier(491                         eAccessPackage));492  EXPECT_EQ(AS_public,493            TypeSystemClang::ConvertAccessTypeToAccessSpecifier(eAccessPublic));494  EXPECT_EQ(AS_private, TypeSystemClang::ConvertAccessTypeToAccessSpecifier(495                            eAccessPrivate));496  EXPECT_EQ(AS_protected, TypeSystemClang::ConvertAccessTypeToAccessSpecifier(497                              eAccessProtected));498}499 500TEST_F(TestTypeSystemClang, TestUnifyAccessSpecifiers) {501  // Unifying two of the same type should return the same type502  EXPECT_EQ(AS_public,503            TypeSystemClang::UnifyAccessSpecifiers(AS_public, AS_public));504  EXPECT_EQ(AS_private,505            TypeSystemClang::UnifyAccessSpecifiers(AS_private, AS_private));506  EXPECT_EQ(AS_protected,507            TypeSystemClang::UnifyAccessSpecifiers(AS_protected, AS_protected));508 509  // Otherwise the result should be the strictest of the two.510  EXPECT_EQ(AS_private,511            TypeSystemClang::UnifyAccessSpecifiers(AS_private, AS_public));512  EXPECT_EQ(AS_private,513            TypeSystemClang::UnifyAccessSpecifiers(AS_private, AS_protected));514  EXPECT_EQ(AS_private,515            TypeSystemClang::UnifyAccessSpecifiers(AS_public, AS_private));516  EXPECT_EQ(AS_private,517            TypeSystemClang::UnifyAccessSpecifiers(AS_protected, AS_private));518  EXPECT_EQ(AS_protected,519            TypeSystemClang::UnifyAccessSpecifiers(AS_protected, AS_public));520  EXPECT_EQ(AS_protected,521            TypeSystemClang::UnifyAccessSpecifiers(AS_public, AS_protected));522 523  // None is stricter than everything (by convention)524  EXPECT_EQ(AS_none,525            TypeSystemClang::UnifyAccessSpecifiers(AS_none, AS_public));526  EXPECT_EQ(AS_none,527            TypeSystemClang::UnifyAccessSpecifiers(AS_none, AS_protected));528  EXPECT_EQ(AS_none,529            TypeSystemClang::UnifyAccessSpecifiers(AS_none, AS_private));530  EXPECT_EQ(AS_none,531            TypeSystemClang::UnifyAccessSpecifiers(AS_public, AS_none));532  EXPECT_EQ(AS_none,533            TypeSystemClang::UnifyAccessSpecifiers(AS_protected, AS_none));534  EXPECT_EQ(AS_none,535            TypeSystemClang::UnifyAccessSpecifiers(AS_private, AS_none));536}537 538TEST_F(TestTypeSystemClang, TestRecordHasFields) {539  CompilerType int_type = m_ast->GetBasicType(eBasicTypeInt);540 541  // Test that a record with no fields returns false542  CompilerType empty_base = m_ast->CreateRecordType(543      nullptr, OptionalClangModuleID(), lldb::eAccessPublic, "EmptyBase",544      llvm::to_underlying(clang::TagTypeKind::Struct),545      lldb::eLanguageTypeC_plus_plus, std::nullopt);546  TypeSystemClang::StartTagDeclarationDefinition(empty_base);547  TypeSystemClang::CompleteTagDeclarationDefinition(empty_base);548 549  RecordDecl *empty_base_decl = TypeSystemClang::GetAsRecordDecl(empty_base);550  EXPECT_NE(nullptr, empty_base_decl);551  EXPECT_FALSE(m_ast->RecordHasFields(empty_base_decl));552 553  // Test that a record with direct fields returns true554  CompilerType non_empty_base = m_ast->CreateRecordType(555      nullptr, OptionalClangModuleID(), lldb::eAccessPublic, "NonEmptyBase",556      llvm::to_underlying(clang::TagTypeKind::Struct),557      lldb::eLanguageTypeC_plus_plus, std::nullopt);558  TypeSystemClang::StartTagDeclarationDefinition(non_empty_base);559  FieldDecl *non_empty_base_field_decl = m_ast->AddFieldToRecordType(560      non_empty_base, "MyField", int_type, eAccessPublic, 0);561  TypeSystemClang::CompleteTagDeclarationDefinition(non_empty_base);562  RecordDecl *non_empty_base_decl =563      TypeSystemClang::GetAsRecordDecl(non_empty_base);564  EXPECT_NE(nullptr, non_empty_base_decl);565  EXPECT_NE(nullptr, non_empty_base_field_decl);566  EXPECT_TRUE(m_ast->RecordHasFields(non_empty_base_decl));567 568  std::vector<std::unique_ptr<clang::CXXBaseSpecifier>> bases;569 570  // Test that a record with no direct fields, but fields in a base returns true571  CompilerType empty_derived = m_ast->CreateRecordType(572      nullptr, OptionalClangModuleID(), lldb::eAccessPublic, "EmptyDerived",573      llvm::to_underlying(clang::TagTypeKind::Struct),574      lldb::eLanguageTypeC_plus_plus, std::nullopt);575  TypeSystemClang::StartTagDeclarationDefinition(empty_derived);576  std::unique_ptr<clang::CXXBaseSpecifier> non_empty_base_spec =577      m_ast->CreateBaseClassSpecifier(non_empty_base.GetOpaqueQualType(),578                                      lldb::eAccessPublic, false, false);579  bases.push_back(std::move(non_empty_base_spec));580  bool result = m_ast->TransferBaseClasses(empty_derived.GetOpaqueQualType(),581                                           std::move(bases));582  TypeSystemClang::CompleteTagDeclarationDefinition(empty_derived);583  EXPECT_TRUE(result);584  CXXRecordDecl *empty_derived_non_empty_base_cxx_decl =585      m_ast->GetAsCXXRecordDecl(empty_derived.GetOpaqueQualType());586  RecordDecl *empty_derived_non_empty_base_decl =587      TypeSystemClang::GetAsRecordDecl(empty_derived);588  EXPECT_EQ(1u, m_ast->GetNumBaseClasses(589                    empty_derived_non_empty_base_cxx_decl, false));590  EXPECT_TRUE(m_ast->RecordHasFields(empty_derived_non_empty_base_decl));591 592  // Test that a record with no direct fields, but fields in a virtual base593  // returns true594  CompilerType empty_derived2 = m_ast->CreateRecordType(595      nullptr, OptionalClangModuleID(), lldb::eAccessPublic, "EmptyDerived2",596      llvm::to_underlying(clang::TagTypeKind::Struct),597      lldb::eLanguageTypeC_plus_plus, std::nullopt);598  TypeSystemClang::StartTagDeclarationDefinition(empty_derived2);599  std::unique_ptr<CXXBaseSpecifier> non_empty_vbase_spec =600      m_ast->CreateBaseClassSpecifier(non_empty_base.GetOpaqueQualType(),601                                      lldb::eAccessPublic, true, false);602  bases.push_back(std::move(non_empty_vbase_spec));603  result = m_ast->TransferBaseClasses(empty_derived2.GetOpaqueQualType(),604                                      std::move(bases));605  TypeSystemClang::CompleteTagDeclarationDefinition(empty_derived2);606  EXPECT_TRUE(result);607  CXXRecordDecl *empty_derived_non_empty_vbase_cxx_decl =608      m_ast->GetAsCXXRecordDecl(empty_derived2.GetOpaqueQualType());609  RecordDecl *empty_derived_non_empty_vbase_decl =610      TypeSystemClang::GetAsRecordDecl(empty_derived2);611  EXPECT_EQ(1u, m_ast->GetNumBaseClasses(612                    empty_derived_non_empty_vbase_cxx_decl, false));613  EXPECT_TRUE(614      m_ast->RecordHasFields(empty_derived_non_empty_vbase_decl));615}616 617TEST_F(TestTypeSystemClang, TemplateArguments) {618  TypeSystemClang::TemplateParameterInfos infos;619  infos.InsertArg("T", TemplateArgument(m_ast->getASTContext().IntTy));620 621  llvm::APSInt arg(llvm::APInt(8, 47));622  infos.InsertArg("I", TemplateArgument(m_ast->getASTContext(), arg,623                                        m_ast->getASTContext().IntTy));624 625  llvm::APFloat float_arg(5.5f);626  infos.InsertArg("F", TemplateArgument(m_ast->getASTContext(),627                                        m_ast->getASTContext().FloatTy,628                                        clang::APValue(float_arg)));629 630  llvm::APFloat double_arg(-15.2);631  infos.InsertArg("D", TemplateArgument(m_ast->getASTContext(),632                                        m_ast->getASTContext().DoubleTy,633                                        clang::APValue(double_arg)));634 635  // template<typename T, int I, float F, double D> struct foo;636  ClassTemplateDecl *decl = m_ast->CreateClassTemplateDecl(637      m_ast->GetTranslationUnitDecl(), OptionalClangModuleID(), eAccessPublic,638      "foo", llvm::to_underlying(clang::TagTypeKind::Struct), infos);639  ASSERT_NE(decl, nullptr);640 641  // foo<int, 47>642  ClassTemplateSpecializationDecl *spec_decl =643      m_ast->CreateClassTemplateSpecializationDecl(644          m_ast->GetTranslationUnitDecl(), OptionalClangModuleID(), decl,645          llvm::to_underlying(clang::TagTypeKind::Struct), infos);646  ASSERT_NE(spec_decl, nullptr);647  CompilerType type = m_ast->CreateClassTemplateSpecializationType(spec_decl);648  ASSERT_TRUE(type);649  m_ast->StartTagDeclarationDefinition(type);650  m_ast->CompleteTagDeclarationDefinition(type);651 652  // typedef foo<int, 47> foo_def;653  CompilerType typedef_type = type.CreateTypedef(654      "foo_def", m_ast->CreateDeclContext(m_ast->GetTranslationUnitDecl()), 0);655 656  CompilerType auto_type(657      m_ast->weak_from_this(),658      m_ast->getASTContext()659          .getAutoType(ClangUtil::GetCanonicalQualType(typedef_type),660                       clang::AutoTypeKeyword::Auto, false)661          .getAsOpaquePtr());662 663  CompilerType int_type(m_ast->weak_from_this(),664                        m_ast->getASTContext().IntTy.getAsOpaquePtr());665  CompilerType float_type(m_ast->weak_from_this(),666                          m_ast->getASTContext().FloatTy.getAsOpaquePtr());667  CompilerType double_type(m_ast->weak_from_this(),668                           m_ast->getASTContext().DoubleTy.getAsOpaquePtr());669  for (CompilerType t : {type, typedef_type, auto_type}) {670    SCOPED_TRACE(t.GetTypeName().AsCString());671 672    const bool expand_pack = false;673    EXPECT_EQ(674        m_ast->GetTemplateArgumentKind(t.GetOpaqueQualType(), 0, expand_pack),675        eTemplateArgumentKindType);676    EXPECT_EQ(677        m_ast->GetTypeTemplateArgument(t.GetOpaqueQualType(), 0, expand_pack),678        int_type);679    EXPECT_EQ(std::nullopt, m_ast->GetIntegralTemplateArgument(680                                t.GetOpaqueQualType(), 0, expand_pack));681 682    EXPECT_EQ(683        m_ast->GetTemplateArgumentKind(t.GetOpaqueQualType(), 1, expand_pack),684        eTemplateArgumentKindIntegral);685    EXPECT_EQ(686        m_ast->GetTypeTemplateArgument(t.GetOpaqueQualType(), 1, expand_pack),687        CompilerType());688    auto result = m_ast->GetIntegralTemplateArgument(t.GetOpaqueQualType(), 1,689                                                     expand_pack);690    ASSERT_NE(std::nullopt, result);691    EXPECT_EQ(arg, result->value.GetAPSInt());692    EXPECT_EQ(int_type, result->type);693 694    EXPECT_EQ(695        m_ast->GetTemplateArgumentKind(t.GetOpaqueQualType(), 2, expand_pack),696        eTemplateArgumentKindStructuralValue);697    EXPECT_EQ(698        m_ast->GetTypeTemplateArgument(t.GetOpaqueQualType(), 2, expand_pack),699        CompilerType());700    auto float_result = m_ast->GetIntegralTemplateArgument(701        t.GetOpaqueQualType(), 2, expand_pack);702    ASSERT_NE(std::nullopt, float_result);703    EXPECT_EQ(float_arg, float_result->value.GetAPFloat());704    EXPECT_EQ(float_type, float_result->type);705 706    EXPECT_EQ(707        m_ast->GetTemplateArgumentKind(t.GetOpaqueQualType(), 3, expand_pack),708        eTemplateArgumentKindStructuralValue);709    EXPECT_EQ(710        m_ast->GetTypeTemplateArgument(t.GetOpaqueQualType(), 3, expand_pack),711        CompilerType());712    auto double_result = m_ast->GetIntegralTemplateArgument(713        t.GetOpaqueQualType(), 3, expand_pack);714    ASSERT_NE(std::nullopt, double_result);715    EXPECT_EQ(double_arg, double_result->value.GetAPFloat());716    EXPECT_EQ(double_type, double_result->type);717  }718}719 720class TestCreateClassTemplateDecl : public TestTypeSystemClang {721protected:722  /// The class templates created so far by the Expect* functions below.723  llvm::DenseSet<ClassTemplateDecl *> m_created_templates;724 725  /// Utility function for creating a class template.726  ClassTemplateDecl *727  CreateClassTemplate(const TypeSystemClang::TemplateParameterInfos &infos) {728    ClassTemplateDecl *decl = m_ast->CreateClassTemplateDecl(729        m_ast->GetTranslationUnitDecl(), OptionalClangModuleID(), eAccessPublic,730        "foo", llvm::to_underlying(clang::TagTypeKind::Struct), infos);731    return decl;732  }733 734  /// Creates a new class template with the given template parameters.735  /// Asserts that a new ClassTemplateDecl is created.736  /// \param description The gtest scope string that should describe the input.737  /// \param infos The template parameters that the class template should have.738  /// \returns The created ClassTemplateDecl.739  ClassTemplateDecl *740  ExpectNewTemplate(std::string description,741                    const TypeSystemClang::TemplateParameterInfos &infos) {742    SCOPED_TRACE(description);743    ClassTemplateDecl *first_template = CreateClassTemplate(infos);744    // A new template should have been created.745    EXPECT_FALSE(m_created_templates.contains(first_template))746        << "Didn't create new class template but reused this existing decl:\n"747        << ClangUtil::DumpDecl(first_template);748    m_created_templates.insert(first_template);749 750    // Creating a new template with the same arguments should always return751    // the template created above.752    ClassTemplateDecl *second_template = CreateClassTemplate(infos);753    EXPECT_EQ(first_template, second_template)754        << "Second attempt to create class template didn't reuse first decl:\n"755        << ClangUtil::DumpDecl(first_template) << "\nInstead created/reused:\n"756        << ClangUtil::DumpDecl(second_template);757    return first_template;758  }759 760  /// Tries to create a new class template but asserts that an existing class761  /// template in the current AST is reused (in contract so a new class762  /// template being created).763  /// \param description The gtest scope string that should describe the input.764  /// \param infos The template parameters that the class template should have.765  void766  ExpectReusedTemplate(std::string description,767                       const TypeSystemClang::TemplateParameterInfos &infos,768                       ClassTemplateDecl *expected) {769    SCOPED_TRACE(description);770    ClassTemplateDecl *td = CreateClassTemplate(infos);771    EXPECT_EQ(td, expected)772        << "Created/reused class template is:\n"773        << ClangUtil::DumpDecl(td) << "\nExpected to reuse:\n"774        << ClangUtil::DumpDecl(expected);775  }776};777 778TEST_F(TestCreateClassTemplateDecl, FindExistingTemplates) {779  // This tests the logic in TypeSystemClang::CreateClassTemplateDecl that780  // decides whether an existing ClassTemplateDecl in the AST can be reused.781  // The behaviour should follow the C++ rules for redeclaring templates782  // (e.g., parameter names can be changed/omitted.)783 784  // Test an empty template parameter list: <>785  ExpectNewTemplate("<>", {{}, {}});786 787  clang::TemplateArgument intArg(m_ast->getASTContext().IntTy);788  clang::TemplateArgument int47Arg(m_ast->getASTContext(),789                                   llvm::APSInt(llvm::APInt(32, 47)),790                                   m_ast->getASTContext().IntTy);791  clang::TemplateArgument floatArg(m_ast->getASTContext().FloatTy);792  clang::TemplateArgument char47Arg(m_ast->getASTContext(),793                                    llvm::APSInt(llvm::APInt(8, 47)),794                                    m_ast->getASTContext().SignedCharTy);795 796  clang::TemplateArgument char123Arg(m_ast->getASTContext(),797                                     llvm::APSInt(llvm::APInt(8, 123)),798                                     m_ast->getASTContext().SignedCharTy);799 800  // Test that <typename T> with T = int creates a new template.801  ClassTemplateDecl *single_type_arg =802      ExpectNewTemplate("<typename T>", {{"T"}, {intArg}});803 804  // Test that changing the parameter name doesn't create a new class template.805  ExpectReusedTemplate("<typename A> (A = int)", {{"A"}, {intArg}},806                       single_type_arg);807 808  // Test that changing the used type doesn't create a new class template.809  ExpectReusedTemplate("<typename A> (A = float)", {{"A"}, {floatArg}},810                       single_type_arg);811 812  // Test that <typename A, signed char I> creates a new template with A = int813  // and I = 47;814  ClassTemplateDecl *type_and_char_value =815      ExpectNewTemplate("<typename A, signed char I> (I = 47)",816                        {{"A", "I"}, {floatArg, char47Arg}});817 818  // Change the value of the I parameter to 123. The previously created819  // class template should still be reused.820  ExpectReusedTemplate("<typename A, signed char I> (I = 123)",821                       {{"A", "I"}, {floatArg, char123Arg}},822                       type_and_char_value);823 824  // Change the type of the I parameter to int so we have <typename A, int I>.825  // The class template from above can't be reused.826  ExpectNewTemplate("<typename A, int I> (I = 123)",827                    {{"A", "I"}, {floatArg, int47Arg}});828 829  // Test a second type parameter will also cause a new template to be created.830  // We now have <typename A, int I, typename B>.831  ClassTemplateDecl *type_and_char_value_and_type =832      ExpectNewTemplate("<typename A, int I, typename B>",833                        {{"A", "I", "B"}, {floatArg, int47Arg, intArg}});834 835  // Remove all the names from the parameters which shouldn't influence the836  // way the templates get merged.837  ExpectReusedTemplate("<typename, int, typename>",838                       {{"", "", ""}, {floatArg, int47Arg, intArg}},839                       type_and_char_value_and_type);840}841 842TEST_F(TestCreateClassTemplateDecl, FindExistingTemplatesWithParameterPack) {843  // The same as FindExistingTemplates but for templates with parameter packs.844  TypeSystemClang::TemplateParameterInfos infos;845  clang::TemplateArgument intArg(m_ast->getASTContext().IntTy);846  clang::TemplateArgument int1Arg(m_ast->getASTContext(),847                                  llvm::APSInt(llvm::APInt(32, 1)),848                                  m_ast->getASTContext().IntTy);849  clang::TemplateArgument int123Arg(m_ast->getASTContext(),850                                    llvm::APSInt(llvm::APInt(32, 123)),851                                    m_ast->getASTContext().IntTy);852  clang::TemplateArgument longArg(m_ast->getASTContext().LongTy);853  clang::TemplateArgument long1Arg(m_ast->getASTContext(),854                                   llvm::APSInt(llvm::APInt(64, 1)),855                                   m_ast->getASTContext().LongTy);856 857  infos.SetParameterPack(858      std::make_unique<TypeSystemClang::TemplateParameterInfos>(859          llvm::SmallVector<const char *>{"", ""},860          llvm::SmallVector<TemplateArgument>{intArg, intArg}));861 862  ClassTemplateDecl *type_pack =863      ExpectNewTemplate("<typename ...> (int, int)", infos);864 865  // Special case: An instantiation for a parameter pack with no values fits866  // to whatever class template we find. There isn't enough information to867  // do an actual comparison here.868  infos.SetParameterPack(869      std::make_unique<TypeSystemClang::TemplateParameterInfos>());870  ExpectReusedTemplate("<...> (no values in pack)", infos, type_pack);871 872  // Change the type content of pack type values.873  infos.SetParameterPack(874      std::make_unique<TypeSystemClang::TemplateParameterInfos>(875          llvm::SmallVector<const char *>{"", ""},876          llvm::SmallVector<TemplateArgument>{intArg, longArg}));877  ExpectReusedTemplate("<typename ...> (int, long)", infos, type_pack);878 879  // Change the number of pack values.880  infos.SetParameterPack(881      std::make_unique<TypeSystemClang::TemplateParameterInfos>(882          llvm::SmallVector<const char *>{""},883          llvm::SmallVector<TemplateArgument>{intArg}));884  ExpectReusedTemplate("<typename ...> (int)", infos, type_pack);885 886  // The names of the pack values shouldn't matter.887  infos.SetParameterPack(888      std::make_unique<TypeSystemClang::TemplateParameterInfos>(889          llvm::SmallVector<const char *>{"A"},890          llvm::SmallVector<TemplateArgument>{intArg}));891  ExpectReusedTemplate("<typename ...> (int)", infos, type_pack);892 893  // Changing the kind of template argument will create a new template.894  infos.SetParameterPack(895      std::make_unique<TypeSystemClang::TemplateParameterInfos>(896          llvm::SmallVector<const char *>{"A"},897          llvm::SmallVector<TemplateArgument>{int1Arg}));898  ClassTemplateDecl *int_pack = ExpectNewTemplate("<int ...> (int = 1)", infos);899 900  // Changing the value of integral parameters will not create a new template.901  infos.SetParameterPack(902      std::make_unique<TypeSystemClang::TemplateParameterInfos>(903          llvm::SmallVector<const char *>{"A"},904          llvm::SmallVector<TemplateArgument>{int123Arg}));905  ExpectReusedTemplate("<int ...> (int = 123)", infos, int_pack);906 907  // Changing the integral type will create a new template.908  infos.SetParameterPack(909      std::make_unique<TypeSystemClang::TemplateParameterInfos>(910          llvm::SmallVector<const char *>{"A"},911          llvm::SmallVector<TemplateArgument>{long1Arg}));912  ExpectNewTemplate("<long ...> (long = 1)", infos);913 914  // Prependinding a non-pack parameter will create a new template.915  infos.InsertArg("T", intArg);916  ExpectNewTemplate("<typename T, long...> (T = int, long = 1)", infos);917}918 919TEST_F(TestTypeSystemClang, OnlyPackName) {920  TypeSystemClang::TemplateParameterInfos infos;921  infos.SetPackName("A");922  EXPECT_FALSE(infos.IsValid());923}924 925static QualType makeConstInt(clang::ASTContext &ctxt) {926  QualType result(ctxt.IntTy);927  result.addConst();928  return result;929}930 931TEST_F(TestTypeSystemClang, TestGetTypeClassDeclType) {932  clang::ASTContext &ctxt = m_ast->getASTContext();933  auto *nullptr_expr = new (ctxt) CXXNullPtrLiteralExpr(ctxt.NullPtrTy, SourceLocation());934  QualType t = ctxt.getDecltypeType(nullptr_expr, makeConstInt(ctxt));935  EXPECT_EQ(lldb::eTypeClassBuiltin, m_ast->GetTypeClass(t.getAsOpaquePtr()));936}937 938TEST_F(TestTypeSystemClang, TestGetTypeClassTypeOf) {939  clang::ASTContext &ctxt = m_ast->getASTContext();940  QualType t = ctxt.getTypeOfType(makeConstInt(ctxt), TypeOfKind::Qualified);941  EXPECT_EQ(lldb::eTypeClassBuiltin, m_ast->GetTypeClass(t.getAsOpaquePtr()));942}943 944TEST_F(TestTypeSystemClang, TestGetTypeClassTypeOfExpr) {945  clang::ASTContext &ctxt = m_ast->getASTContext();946  auto *nullptr_expr = new (ctxt) CXXNullPtrLiteralExpr(ctxt.NullPtrTy, SourceLocation());947  QualType t = ctxt.getTypeOfExprType(nullptr_expr, TypeOfKind::Qualified);948  EXPECT_EQ(lldb::eTypeClassBuiltin, m_ast->GetTypeClass(t.getAsOpaquePtr()));949}950 951TEST_F(TestTypeSystemClang, TestGetTypeClassNested) {952  clang::ASTContext &ctxt = m_ast->getASTContext();953  QualType t_base =954      ctxt.getTypeOfType(makeConstInt(ctxt), TypeOfKind::Qualified);955  QualType t = ctxt.getTypeOfType(t_base, TypeOfKind::Qualified);956  EXPECT_EQ(lldb::eTypeClassBuiltin, m_ast->GetTypeClass(t.getAsOpaquePtr()));957}958 959TEST_F(TestTypeSystemClang, TestFunctionTemplateConstruction) {960  // Tests creating a function template.961 962  CompilerType int_type = m_ast->GetBasicType(lldb::eBasicTypeInt);963  clang::TranslationUnitDecl *TU = m_ast->GetTranslationUnitDecl();964 965  // Prepare the declarations/types we need for the template.966  CompilerType clang_type = m_ast->CreateFunctionType(int_type, {}, false, 0U);967  FunctionDecl *func = m_ast->CreateFunctionDeclaration(968      TU, OptionalClangModuleID(), "foo", clang_type, StorageClass::SC_None,969      false, /*asm_label=*/{});970  TypeSystemClang::TemplateParameterInfos empty_params;971 972  // Create the actual function template.973  clang::FunctionTemplateDecl *func_template =974      m_ast->CreateFunctionTemplateDecl(TU, OptionalClangModuleID(), func,975                                        empty_params);976 977  EXPECT_EQ(TU, func_template->getDeclContext());978  EXPECT_EQ("foo", func_template->getName());979  EXPECT_EQ(clang::AccessSpecifier::AS_none, func_template->getAccess());980}981 982TEST_F(TestTypeSystemClang, TestFunctionTemplateInRecordConstruction) {983  // Tests creating a function template inside a record.984 985  CompilerType int_type = m_ast->GetBasicType(lldb::eBasicTypeInt);986  clang::TranslationUnitDecl *TU = m_ast->GetTranslationUnitDecl();987 988  // Create a record we can put the function template int.989  CompilerType record_type =990      clang_utils::createRecordWithField(*m_ast, "record", int_type, "field");991  clang::TagDecl *record = ClangUtil::GetAsTagDecl(record_type);992 993  // Prepare the declarations/types we need for the template.994  CompilerType clang_type = m_ast->CreateFunctionType(int_type, {}, false, 0U);995  // We create the FunctionDecl for the template in the TU DeclContext because:996  // 1. FunctionDecls can't be in a Record (only CXXMethodDecls can).997  // 2. It is mirroring the behavior of DWARFASTParserClang::ParseSubroutine.998  FunctionDecl *func = m_ast->CreateFunctionDeclaration(999      TU, OptionalClangModuleID(), "foo", clang_type, StorageClass::SC_None,1000      false, /*asm_label=*/{});1001  TypeSystemClang::TemplateParameterInfos empty_params;1002 1003  // Create the actual function template.1004  clang::FunctionTemplateDecl *func_template =1005      m_ast->CreateFunctionTemplateDecl(record, OptionalClangModuleID(), func,1006                                        empty_params);1007 1008  EXPECT_EQ(record, func_template->getDeclContext());1009  EXPECT_EQ("foo", func_template->getName());1010  EXPECT_EQ(clang::AccessSpecifier::AS_public, func_template->getAccess());1011}1012 1013TEST_F(TestTypeSystemClang, TestDeletingImplicitCopyCstrDueToMoveCStr) {1014  // We need to simulate this behavior in our AST that we construct as we don't1015  // have a Sema instance that can do this for us:1016  // C++11 [class.copy]p7, p18:1017  //  If the class definition declares a move constructor or move assignment1018  //  operator, an implicitly declared copy constructor or copy assignment1019  //  operator is defined as deleted.1020 1021  // Create a record and start defining it.1022  llvm::StringRef class_name = "S";1023  CompilerType t = clang_utils::createRecord(*m_ast, class_name);1024  m_ast->StartTagDeclarationDefinition(t);1025 1026  // Create a move constructor that will delete the implicit copy constructor.1027  CompilerType return_type = m_ast->GetBasicType(lldb::eBasicTypeVoid);1028  std::array<CompilerType, 1> args{t.GetRValueReferenceType()};1029  CompilerType function_type = m_ast->CreateFunctionType(1030      return_type, args, /*variadic=*/false, /*quals*/ 0U);1031  bool is_virtual = false;1032  bool is_static = false;1033  bool is_inline = false;1034  bool is_explicit = true;1035  bool is_attr_used = false;1036  bool is_artificial = false;1037  m_ast->AddMethodToCXXRecordType(1038      t.GetOpaqueQualType(), class_name, /*asm_label=*/{}, function_type,1039      lldb::AccessType::eAccessPublic, is_virtual, is_static, is_inline,1040      is_explicit, is_attr_used, is_artificial);1041 1042  // Complete the definition and check the created record.1043  m_ast->CompleteTagDeclarationDefinition(t);1044  auto *record = llvm::cast<CXXRecordDecl>(ClangUtil::GetAsTagDecl(t));1045  // We can't call defaultedCopyConstructorIsDeleted() as this requires that1046  // the Decl passes through Sema which will actually compute this field.1047  // Instead we check that there is no copy constructor declared by the user1048  // which only leaves a non-deleted defaulted copy constructor as an option1049  // that our record will have no simple copy constructor.1050  EXPECT_FALSE(record->hasUserDeclaredCopyConstructor());1051  EXPECT_FALSE(record->hasSimpleCopyConstructor());1052}1053 1054TEST_F(TestTypeSystemClang, TestNotDeletingUserCopyCstrDueToMoveCStr) {1055  // Tests that we don't delete the a user-defined copy constructor when1056  // a move constructor is provided.1057  // See also the TestDeletingImplicitCopyCstrDueToMoveCStr test.1058  llvm::StringRef class_name = "S";1059  CompilerType t = clang_utils::createRecord(*m_ast, class_name);1060  m_ast->StartTagDeclarationDefinition(t);1061 1062  CompilerType return_type = m_ast->GetBasicType(lldb::eBasicTypeVoid);1063  bool is_virtual = false;1064  bool is_static = false;1065  bool is_inline = false;1066  bool is_explicit = true;1067  bool is_attr_used = false;1068  bool is_artificial = false;1069  // Create a move constructor.1070  {1071    std::array<CompilerType, 1> args{t.GetRValueReferenceType()};1072    CompilerType function_type = m_ast->CreateFunctionType(1073        return_type, args, /*variadic=*/false, /*quals*/ 0U);1074    m_ast->AddMethodToCXXRecordType(1075        t.GetOpaqueQualType(), class_name, /*asm_label=*/{}, function_type,1076        lldb::AccessType::eAccessPublic, is_virtual, is_static, is_inline,1077        is_explicit, is_attr_used, is_artificial);1078  }1079  // Create a copy constructor.1080  {1081    std::array<CompilerType, 1> args{1082        t.GetLValueReferenceType().AddConstModifier()};1083    CompilerType function_type =1084        m_ast->CreateFunctionType(return_type, args,1085                                  /*variadic=*/false, /*quals*/ 0U);1086    m_ast->AddMethodToCXXRecordType(1087        t.GetOpaqueQualType(), class_name, /*asm_label=*/{}, function_type,1088        lldb::AccessType::eAccessPublic, is_virtual, is_static, is_inline,1089        is_explicit, is_attr_used, is_artificial);1090  }1091 1092  // Complete the definition and check the created record.1093  m_ast->CompleteTagDeclarationDefinition(t);1094  auto *record = llvm::cast<CXXRecordDecl>(ClangUtil::GetAsTagDecl(t));1095  EXPECT_TRUE(record->hasUserDeclaredCopyConstructor());1096}1097 1098TEST_F(TestTypeSystemClang, AddMethodToObjCObjectType) {1099  // Create an interface decl and mark it as having external storage.1100  CompilerType c = m_ast->CreateObjCClass("A", m_ast->GetTranslationUnitDecl(),1101                                          OptionalClangModuleID(),1102                                          /*IsInternal*/ false);1103  ObjCInterfaceDecl *interface = m_ast->GetAsObjCInterfaceDecl(c);1104  m_ast->SetHasExternalStorage(c.GetOpaqueQualType(), true);1105  EXPECT_TRUE(interface->hasExternalLexicalStorage());1106 1107  // Add a method to the interface.1108  std::vector<CompilerType> args;1109  CompilerType func_type = m_ast->CreateFunctionType(1110      m_ast->GetBasicType(lldb::eBasicTypeInt), args, /*variadic*/ false,1111      /*quals*/ 0, clang::CallingConv::CC_C);1112  bool variadic = false;1113  bool artificial = false;1114  bool objc_direct = false;1115  clang::ObjCMethodDecl *method = TypeSystemClang::AddMethodToObjCObjectType(1116      c, "-[A foo]", func_type, artificial, variadic, objc_direct);1117  ASSERT_NE(method, nullptr);1118 1119  // The interface decl should still have external lexical storage.1120  EXPECT_TRUE(interface->hasExternalLexicalStorage());1121 1122  // Test some properties of the created ObjCMethodDecl.1123  EXPECT_FALSE(method->isVariadic());1124  EXPECT_TRUE(method->isImplicit());1125  EXPECT_FALSE(method->isDirectMethod());1126  EXPECT_EQ(method->getDeclName().getObjCSelector().getAsString(), "foo");1127}1128 1129TEST_F(TestTypeSystemClang, GetFullyUnqualifiedType) {1130  CompilerType bool_ = m_ast->GetBasicType(eBasicTypeBool);1131  CompilerType cv_bool = bool_.AddConstModifier().AddVolatileModifier();1132 1133  // const volatile bool -> bool1134  EXPECT_EQ(bool_, cv_bool.GetFullyUnqualifiedType());1135 1136  // const volatile bool[47] -> bool[47]1137  EXPECT_EQ(bool_.GetArrayType(47),1138            cv_bool.GetArrayType(47).GetFullyUnqualifiedType());1139 1140  // const volatile bool[47][42] -> bool[47][42]1141  EXPECT_EQ(1142      bool_.GetArrayType(42).GetArrayType(47),1143      cv_bool.GetArrayType(42).GetArrayType(47).GetFullyUnqualifiedType());1144 1145  // const volatile bool * -> bool *1146  EXPECT_EQ(bool_.GetPointerType(),1147            cv_bool.GetPointerType().GetFullyUnqualifiedType());1148 1149  // const volatile bool *[47] -> bool *[47]1150  EXPECT_EQ(1151      bool_.GetPointerType().GetArrayType(47),1152      cv_bool.GetPointerType().GetArrayType(47).GetFullyUnqualifiedType());1153}1154 1155TEST(TestScratchTypeSystemClang, InferSubASTFromLangOpts) {1156  LangOptions lang_opts;1157  EXPECT_EQ(1158      ScratchTypeSystemClang::DefaultAST,1159      ScratchTypeSystemClang::InferIsolatedASTKindFromLangOpts(lang_opts));1160 1161  lang_opts.Modules = true;1162  EXPECT_EQ(1163      ScratchTypeSystemClang::IsolatedASTKind::CppModules,1164      ScratchTypeSystemClang::InferIsolatedASTKindFromLangOpts(lang_opts));1165}1166 1167TEST_F(TestTypeSystemClang, GetDeclContextByNameWhenMissingSymbolFile) {1168  // Test that a type system without a symbol file is handled gracefully.1169  std::vector<CompilerDecl> decls =1170      m_ast->DeclContextFindDeclByName(nullptr, ConstString("SomeName"), true);1171 1172  EXPECT_TRUE(decls.empty());1173}1174 1175TEST_F(TestTypeSystemClang, AddMethodToCXXRecordType_ParmVarDecls) {1176  // Tests that AddMethodToCXXRecordType creates ParmVarDecl's with1177  // a correct clang::DeclContext.1178 1179  llvm::StringRef class_name = "S";1180  CompilerType t = clang_utils::createRecord(*m_ast, class_name);1181  m_ast->StartTagDeclarationDefinition(t);1182 1183  CompilerType return_type = m_ast->GetBasicType(lldb::eBasicTypeVoid);1184  const bool is_virtual = false;1185  const bool is_static = false;1186  const bool is_inline = false;1187  const bool is_explicit = true;1188  const bool is_attr_used = false;1189  const bool is_artificial = false;1190 1191  llvm::SmallVector<CompilerType> param_types{1192      m_ast->GetBasicType(lldb::eBasicTypeInt),1193      m_ast->GetBasicType(lldb::eBasicTypeShort)};1194  CompilerType function_type =1195      m_ast->CreateFunctionType(return_type, param_types,1196                                /*variadic=*/false, /*quals*/ 0U);1197  m_ast->AddMethodToCXXRecordType(1198      t.GetOpaqueQualType(), "myFunc", /*asm_label=*/{}, function_type,1199      lldb::AccessType::eAccessPublic, is_virtual, is_static, is_inline,1200      is_explicit, is_attr_used, is_artificial);1201 1202  // Complete the definition and check the created record.1203  m_ast->CompleteTagDeclarationDefinition(t);1204 1205  auto *record = llvm::cast<CXXRecordDecl>(ClangUtil::GetAsTagDecl(t));1206 1207  auto method_it = record->method_begin();1208  ASSERT_NE(method_it, record->method_end());1209 1210  EXPECT_EQ(method_it->getNumParams(), param_types.size());1211 1212  // DeclContext of each parameter should be the CXXMethodDecl itself.1213  EXPECT_EQ(method_it->getParamDecl(0)->getDeclContext(), *method_it);1214  EXPECT_EQ(method_it->getParamDecl(1)->getDeclContext(), *method_it);1215}1216 1217TEST_F(TestTypeSystemClang, TestGetTypeInfo) {1218  // Tests TypeSystemClang::GetTypeInfo1219 1220  const ASTContext &ast = m_ast->getASTContext();1221 1222  CompilerType complex_int = m_ast->GetType(ast.getComplexType(ast.IntTy));1223  EXPECT_EQ(complex_int.GetTypeInfo(),1224            (eTypeIsInteger | eTypeIsComplex | eTypeIsBuiltIn | eTypeHasValue));1225 1226  CompilerType complex_float = m_ast->GetType(ast.getComplexType(ast.FloatTy));1227  EXPECT_EQ(complex_float.GetTypeInfo(),1228            (eTypeIsFloat | eTypeIsComplex | eTypeIsBuiltIn | eTypeHasValue));1229 1230  CompilerType vector_of_int =1231      m_ast->GetType(ast.getVectorType(ast.IntTy, 1, VectorKind::Generic));1232  EXPECT_EQ(vector_of_int.GetTypeInfo(),1233            (eTypeIsInteger | eTypeIsVector | eTypeHasChildren));1234 1235  CompilerType vector_of_float =1236      m_ast->GetType(ast.getVectorType(ast.FloatTy, 1, VectorKind::Generic));1237  EXPECT_EQ(vector_of_float.GetTypeInfo(),1238            (eTypeIsFloat | eTypeIsVector | eTypeHasChildren));1239}1240 1241TEST_F(TestTypeSystemClang, AsmLabel_CtorDtor) {1242  // Tests TypeSystemClang::DeclGetMangledName for constructors/destructors1243  // with and without AsmLabels.1244 1245  llvm::StringRef class_name = "S";1246  CompilerType t = clang_utils::createRecord(*m_ast, class_name);1247  m_ast->StartTagDeclarationDefinition(t);1248 1249  CompilerType return_type = m_ast->GetBasicType(lldb::eBasicTypeVoid);1250  const bool is_virtual = false;1251  const bool is_static = false;1252  const bool is_inline = false;1253  const bool is_explicit = true;1254  const bool is_attr_used = false;1255  const bool is_artificial = false;1256 1257  CompilerType function_type =1258      m_ast->CreateFunctionType(return_type, {},1259                                /*variadic=*/false, /*quals*/ 0U);1260  auto *ctor_nolabel = m_ast->AddMethodToCXXRecordType(1261      t.GetOpaqueQualType(), "S", /*asm_label=*/{}, function_type,1262      lldb::AccessType::eAccessPublic, is_virtual, is_static, is_inline,1263      is_explicit, is_attr_used, is_artificial);1264 1265  auto *dtor_nolabel = m_ast->AddMethodToCXXRecordType(1266      t.GetOpaqueQualType(), "~S", /*asm_label=*/{}, function_type,1267      lldb::AccessType::eAccessPublic, is_virtual, is_static, is_inline,1268      is_explicit, is_attr_used, is_artificial);1269 1270  auto *ctor = m_ast->AddMethodToCXXRecordType(1271      t.GetOpaqueQualType(), "S", /*asm_label=*/"$__lldb_func::0x0:0x0:S",1272      function_type, lldb::AccessType::eAccessPublic, is_virtual, is_static,1273      is_inline, is_explicit, is_attr_used, is_artificial);1274 1275  auto *dtor = m_ast->AddMethodToCXXRecordType(1276      t.GetOpaqueQualType(), "~S", /*asm_label=*/"$__lldb_func::0x0:0x0:~S",1277      function_type, lldb::AccessType::eAccessPublic, is_virtual, is_static,1278      is_inline, is_explicit, is_attr_used, is_artificial);1279 1280  m_ast->CompleteTagDeclarationDefinition(t);1281 1282  ASSERT_TRUE(ctor_nolabel);1283  ASSERT_TRUE(dtor_nolabel);1284  ASSERT_TRUE(ctor);1285  ASSERT_TRUE(dtor);1286 1287#ifdef _WIN321288  EXPECT_STREQ(m_ast->DeclGetMangledName(ctor_nolabel).GetCString(),1289               "??0S@@QEAA@XZ");1290  EXPECT_STREQ(m_ast->DeclGetMangledName(dtor_nolabel).GetCString(),1291               "??_DS@@QEAAXXZ");1292#else1293  EXPECT_STREQ(m_ast->DeclGetMangledName(ctor_nolabel).GetCString(),1294               "_ZN1SC1Ev");1295  EXPECT_STREQ(m_ast->DeclGetMangledName(dtor_nolabel).GetCString(),1296               "_ZN1SD1Ev");1297#endif1298 1299  EXPECT_STREQ(llvm::GlobalValue::dropLLVMManglingEscape(1300                   m_ast->DeclGetMangledName(ctor).GetStringRef())1301                   .data(),1302               "$__lldb_func:C0:0x0:0x0:S");1303  EXPECT_STREQ(llvm::GlobalValue::dropLLVMManglingEscape(1304                   m_ast->DeclGetMangledName(dtor).GetStringRef())1305                   .data(),1306               "$__lldb_func:D1:0x0:0x0:~S");1307}1308 1309struct AsmLabelTestCase {1310  llvm::StringRef mangled;1311  llvm::StringRef expected;1312};1313 1314class TestTypeSystemClangAsmLabel1315    : public testing::TestWithParam<AsmLabelTestCase> {1316public:1317  SubsystemRAII<FileSystem, HostInfo> subsystems;1318 1319  void SetUp() override {1320    m_holder =1321        std::make_unique<clang_utils::TypeSystemClangHolder>("test ASTContext");1322    m_ast = m_holder->GetAST();1323  }1324 1325  void TearDown() override {1326    m_ast = nullptr;1327    m_holder.reset();1328  }1329 1330protected:1331  TypeSystemClang *m_ast = nullptr;1332  std::unique_ptr<clang_utils::TypeSystemClangHolder> m_holder;1333};1334 1335static AsmLabelTestCase g_asm_label_test_cases[] = {1336    {/*mangled=*/"$__lldb_func::0x0:0x0:_Z3foov",1337     /*expected=*/"_Z3foov"},1338    {/*mangled=*/"$__lldb_func::0x0:0x0:foo",1339     /*expected=*/"$__lldb_func::0x0:0x0:foo"},1340    {/*mangled=*/"foo",1341     /*expected=*/"foo"},1342    {/*mangled=*/"_Z3foov",1343     /*expected=*/"_Z3foov"},1344    {/*mangled=*/"$__lldb_func:",1345     /*expected=*/"$__lldb_func:"},1346};1347 1348TEST_P(TestTypeSystemClangAsmLabel, DeclGetMangledName) {1349  const auto &[mangled, expected] = GetParam();1350 1351  CompilerType int_type = m_ast->GetBasicType(lldb::eBasicTypeInt);1352  clang::TranslationUnitDecl *TU = m_ast->GetTranslationUnitDecl();1353 1354  // Prepare the declarations/types we need for the template.1355  CompilerType clang_type = m_ast->CreateFunctionType(int_type, {}, false, 0U);1356  FunctionDecl *func = m_ast->CreateFunctionDeclaration(1357      TU, OptionalClangModuleID(), "foo", clang_type, StorageClass::SC_None,1358      false, /*asm_label=*/mangled);1359 1360  ASSERT_EQ(llvm::GlobalValue::dropLLVMManglingEscape(1361                m_ast->DeclGetMangledName(func).GetStringRef()),1362            expected);1363}1364 1365INSTANTIATE_TEST_SUITE_P(AsmLabelTests, TestTypeSystemClangAsmLabel,1366                         testing::ValuesIn(g_asm_label_test_cases));1367