//===-- TestTypeSystemClang.cpp -------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "Plugins/ExpressionParser/Clang/ClangUtil.h"
#include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
#include "TestingSupport/SubsystemRAII.h"
#include "TestingSupport/Symbol/ClangTestUtils.h"
#include "lldb/Core/Declaration.h"
#include "lldb/Host/FileSystem.h"
#include "lldb/Host/HostInfo.h"
#include "clang/AST/DeclCXX.h"
#include "clang/AST/DeclObjC.h"
#include "clang/AST/ExprCXX.h"
#include "gtest/gtest.h"

using namespace clang;
using namespace lldb;
using namespace lldb_private;

class TestTypeSystemClang : public testing::Test {
public:
  SubsystemRAII<FileSystem, HostInfo> subsystems;

  void SetUp() override {
    m_ast.reset(
        new TypeSystemClang("test ASTContext", HostInfo::GetTargetTriple()));
  }

  void TearDown() override { m_ast.reset(); }

protected:
  std::unique_ptr<TypeSystemClang> m_ast;

  QualType GetBasicQualType(BasicType type) const {
    return ClangUtil::GetQualType(m_ast->GetBasicTypeFromAST(type));
  }

  QualType GetBasicQualType(const char *name) const {
    return ClangUtil::GetQualType(
        m_ast->GetBuiltinTypeByName(ConstString(name)));
  }
};

TEST_F(TestTypeSystemClang, TestGetBasicTypeFromEnum) {
  clang::ASTContext &context = m_ast->getASTContext();

  EXPECT_TRUE(
      context.hasSameType(GetBasicQualType(eBasicTypeBool), context.BoolTy));
  EXPECT_TRUE(
      context.hasSameType(GetBasicQualType(eBasicTypeChar), context.CharTy));
  EXPECT_TRUE(context.hasSameType(GetBasicQualType(eBasicTypeChar8),
                                  context.Char8Ty));
  EXPECT_TRUE(context.hasSameType(GetBasicQualType(eBasicTypeChar16),
                                  context.Char16Ty));
  EXPECT_TRUE(context.hasSameType(GetBasicQualType(eBasicTypeChar32),
                                  context.Char32Ty));
  EXPECT_TRUE(context.hasSameType(GetBasicQualType(eBasicTypeDouble),
                                  context.DoubleTy));
  EXPECT_TRUE(context.hasSameType(GetBasicQualType(eBasicTypeDoubleComplex),
                                  context.getComplexType(context.DoubleTy)));
  EXPECT_TRUE(
      context.hasSameType(GetBasicQualType(eBasicTypeFloat), context.FloatTy));
  EXPECT_TRUE(context.hasSameType(GetBasicQualType(eBasicTypeFloatComplex),
                                  context.getComplexType(context.FloatTy)));
  EXPECT_TRUE(
      context.hasSameType(GetBasicQualType(eBasicTypeHalf), context.HalfTy));
  EXPECT_TRUE(
      context.hasSameType(GetBasicQualType(eBasicTypeInt), context.IntTy));
  EXPECT_TRUE(context.hasSameType(GetBasicQualType(eBasicTypeInt128),
                                  context.Int128Ty));
  EXPECT_TRUE(
      context.hasSameType(GetBasicQualType(eBasicTypeLong), context.LongTy));
  EXPECT_TRUE(context.hasSameType(GetBasicQualType(eBasicTypeLongDouble),
                                  context.LongDoubleTy));
  EXPECT_TRUE(
      context.hasSameType(GetBasicQualType(eBasicTypeLongDoubleComplex),
                          context.getComplexType(context.LongDoubleTy)));
  EXPECT_TRUE(context.hasSameType(GetBasicQualType(eBasicTypeLongLong),
                                  context.LongLongTy));
  EXPECT_TRUE(context.hasSameType(GetBasicQualType(eBasicTypeNullPtr),
                                  context.NullPtrTy));
  EXPECT_TRUE(context.hasSameType(GetBasicQualType(eBasicTypeObjCClass),
                                  context.getObjCClassType()));
  EXPECT_TRUE(context.hasSameType(GetBasicQualType(eBasicTypeObjCID),
                                  context.getObjCIdType()));
  EXPECT_TRUE(context.hasSameType(GetBasicQualType(eBasicTypeObjCSel),
                                  context.getObjCSelType()));
  EXPECT_TRUE(
      context.hasSameType(GetBasicQualType(eBasicTypeShort), context.ShortTy));
  EXPECT_TRUE(context.hasSameType(GetBasicQualType(eBasicTypeSignedChar),
                                  context.SignedCharTy));
  EXPECT_TRUE(context.hasSameType(GetBasicQualType(eBasicTypeUnsignedChar),
                                  context.UnsignedCharTy));
  EXPECT_TRUE(context.hasSameType(GetBasicQualType(eBasicTypeUnsignedInt),
                                  context.UnsignedIntTy));
  EXPECT_TRUE(context.hasSameType(GetBasicQualType(eBasicTypeUnsignedInt128),
                                  context.UnsignedInt128Ty));
  EXPECT_TRUE(context.hasSameType(GetBasicQualType(eBasicTypeUnsignedLong),
                                  context.UnsignedLongTy));
  EXPECT_TRUE(context.hasSameType(GetBasicQualType(eBasicTypeUnsignedLongLong),
                                  context.UnsignedLongLongTy));
  EXPECT_TRUE(context.hasSameType(GetBasicQualType(eBasicTypeUnsignedShort),
                                  context.UnsignedShortTy));
  EXPECT_TRUE(
      context.hasSameType(GetBasicQualType(eBasicTypeVoid), context.VoidTy));
  EXPECT_TRUE(
      context.hasSameType(GetBasicQualType(eBasicTypeWChar), context.WCharTy));
}

TEST_F(TestTypeSystemClang, TestGetBasicTypeFromName) {
  EXPECT_EQ(GetBasicQualType(eBasicTypeChar), GetBasicQualType("char"));
  EXPECT_EQ(GetBasicQualType(eBasicTypeSignedChar),
            GetBasicQualType("signed char"));
  EXPECT_EQ(GetBasicQualType(eBasicTypeUnsignedChar),
            GetBasicQualType("unsigned char"));
  EXPECT_EQ(GetBasicQualType(eBasicTypeWChar), GetBasicQualType("wchar_t"));
  EXPECT_EQ(GetBasicQualType(eBasicTypeSignedWChar),
            GetBasicQualType("signed wchar_t"));
  EXPECT_EQ(GetBasicQualType(eBasicTypeUnsignedWChar),
            GetBasicQualType("unsigned wchar_t"));
  EXPECT_EQ(GetBasicQualType(eBasicTypeShort), GetBasicQualType("short"));
  EXPECT_EQ(GetBasicQualType(eBasicTypeShort), GetBasicQualType("short int"));
  EXPECT_EQ(GetBasicQualType(eBasicTypeUnsignedShort),
            GetBasicQualType("unsigned short"));
  EXPECT_EQ(GetBasicQualType(eBasicTypeUnsignedShort),
            GetBasicQualType("unsigned short int"));
  EXPECT_EQ(GetBasicQualType(eBasicTypeInt), GetBasicQualType("int"));
  EXPECT_EQ(GetBasicQualType(eBasicTypeInt), GetBasicQualType("signed int"));
  EXPECT_EQ(GetBasicQualType(eBasicTypeUnsignedInt),
            GetBasicQualType("unsigned int"));
  EXPECT_EQ(GetBasicQualType(eBasicTypeUnsignedInt),
            GetBasicQualType("unsigned"));
  EXPECT_EQ(GetBasicQualType(eBasicTypeLong), GetBasicQualType("long"));
  EXPECT_EQ(GetBasicQualType(eBasicTypeLong), GetBasicQualType("long int"));
  EXPECT_EQ(GetBasicQualType(eBasicTypeUnsignedLong),
            GetBasicQualType("unsigned long"));
  EXPECT_EQ(GetBasicQualType(eBasicTypeUnsignedLong),
            GetBasicQualType("unsigned long int"));
  EXPECT_EQ(GetBasicQualType(eBasicTypeLongLong),
            GetBasicQualType("long long"));
  EXPECT_EQ(GetBasicQualType(eBasicTypeLongLong),
            GetBasicQualType("long long int"));
  EXPECT_EQ(GetBasicQualType(eBasicTypeUnsignedLongLong),
            GetBasicQualType("unsigned long long"));
  EXPECT_EQ(GetBasicQualType(eBasicTypeUnsignedLongLong),
            GetBasicQualType("unsigned long long int"));
  EXPECT_EQ(GetBasicQualType(eBasicTypeInt128), GetBasicQualType("__int128_t"));
  EXPECT_EQ(GetBasicQualType(eBasicTypeUnsignedInt128),
            GetBasicQualType("__uint128_t"));
  EXPECT_EQ(GetBasicQualType(eBasicTypeVoid), GetBasicQualType("void"));
  EXPECT_EQ(GetBasicQualType(eBasicTypeBool), GetBasicQualType("bool"));
  EXPECT_EQ(GetBasicQualType(eBasicTypeFloat), GetBasicQualType("float"));
  EXPECT_EQ(GetBasicQualType(eBasicTypeDouble), GetBasicQualType("double"));
  EXPECT_EQ(GetBasicQualType(eBasicTypeLongDouble),
            GetBasicQualType("long double"));
  EXPECT_EQ(GetBasicQualType(eBasicTypeObjCID), GetBasicQualType("id"));
  EXPECT_EQ(GetBasicQualType(eBasicTypeObjCSel), GetBasicQualType("SEL"));
  EXPECT_EQ(GetBasicQualType(eBasicTypeNullPtr), GetBasicQualType("nullptr"));
}

void VerifyEncodingAndBitSize(TypeSystemClang &clang_context,
                              lldb::Encoding encoding, unsigned int bit_size) {
  clang::ASTContext &context = clang_context.getASTContext();

  CompilerType type =
      clang_context.GetBuiltinTypeForEncodingAndBitSize(encoding, bit_size);
  EXPECT_TRUE(type.IsValid());

  QualType qtype = ClangUtil::GetQualType(type);
  EXPECT_FALSE(qtype.isNull());
  if (qtype.isNull())
    return;

  uint64_t actual_size = context.getTypeSize(qtype);
  EXPECT_EQ(bit_size, actual_size);

  const clang::Type *type_ptr = qtype.getTypePtr();
  EXPECT_NE(nullptr, type_ptr);
  if (!type_ptr)
    return;

  EXPECT_TRUE(type_ptr->isBuiltinType());
  switch (encoding) {
  case eEncodingSint:
    EXPECT_TRUE(type_ptr->isSignedIntegerType());
    break;
  case eEncodingUint:
    EXPECT_TRUE(type_ptr->isUnsignedIntegerType());
    break;
  case eEncodingIEEE754:
    EXPECT_TRUE(type_ptr->isFloatingType());
    break;
  default:
    FAIL() << "Unexpected encoding";
    break;
  }
}

TEST_F(TestTypeSystemClang, TestBuiltinTypeForEncodingAndBitSize) {
  // Make sure we can get types of every possible size in every possible
  // encoding.
  // We can't make any guarantee about which specific type we get, because the
  // standard
  // isn't that specific.  We only need to make sure the compiler hands us some
  // type that
  // is both a builtin type and matches the requested bit size.
  VerifyEncodingAndBitSize(*m_ast, eEncodingSint, 8);
  VerifyEncodingAndBitSize(*m_ast, eEncodingSint, 16);
  VerifyEncodingAndBitSize(*m_ast, eEncodingSint, 32);
  VerifyEncodingAndBitSize(*m_ast, eEncodingSint, 64);
  VerifyEncodingAndBitSize(*m_ast, eEncodingSint, 128);

  VerifyEncodingAndBitSize(*m_ast, eEncodingUint, 8);
  VerifyEncodingAndBitSize(*m_ast, eEncodingUint, 16);
  VerifyEncodingAndBitSize(*m_ast, eEncodingUint, 32);
  VerifyEncodingAndBitSize(*m_ast, eEncodingUint, 64);
  VerifyEncodingAndBitSize(*m_ast, eEncodingUint, 128);

  VerifyEncodingAndBitSize(*m_ast, eEncodingIEEE754, 32);
  VerifyEncodingAndBitSize(*m_ast, eEncodingIEEE754, 64);
}

TEST_F(TestTypeSystemClang, TestDisplayName) {
  TypeSystemClang ast("some name", llvm::Triple());
  EXPECT_EQ("some name", ast.getDisplayName());
}

TEST_F(TestTypeSystemClang, TestDisplayNameEmpty) {
  TypeSystemClang ast("", llvm::Triple());
  EXPECT_EQ("", ast.getDisplayName());
}

TEST_F(TestTypeSystemClang, TestGetEnumIntegerTypeInvalid) {
  EXPECT_FALSE(m_ast->GetEnumerationIntegerType(CompilerType()).IsValid());
}

TEST_F(TestTypeSystemClang, TestGetEnumIntegerTypeUnexpectedType) {
  CompilerType int_type = m_ast->GetBasicType(lldb::eBasicTypeInt);
  CompilerType t = m_ast->GetEnumerationIntegerType(int_type);
  EXPECT_FALSE(t.IsValid());
}

TEST_F(TestTypeSystemClang, TestGetEnumIntegerTypeBasicTypes) {
  // All possible underlying integer types of enums.
  const std::vector<lldb::BasicType> types_to_test = {
      eBasicTypeInt,          eBasicTypeUnsignedInt, eBasicTypeLong,
      eBasicTypeUnsignedLong, eBasicTypeLongLong,    eBasicTypeUnsignedLongLong,
  };

  for (bool scoped : {true, false}) {
    SCOPED_TRACE("scoped: " + std::to_string(scoped));
    for (lldb::BasicType basic_type : types_to_test) {
      SCOPED_TRACE(std::to_string(basic_type));

      TypeSystemClang ast("enum_ast", HostInfo::GetTargetTriple());
      CompilerType basic_compiler_type = ast.GetBasicType(basic_type);
      EXPECT_TRUE(basic_compiler_type.IsValid());

      CompilerType enum_type = ast.CreateEnumerationType(
          "my_enum", ast.GetTranslationUnitDecl(), OptionalClangModuleID(),
          Declaration(), basic_compiler_type, scoped);

      CompilerType t = ast.GetEnumerationIntegerType(enum_type);
      // Check that the type we put in at the start is found again.
      EXPECT_EQ(basic_compiler_type.GetTypeName(), t.GetTypeName());
    }
  }
}

TEST_F(TestTypeSystemClang, TestOwningModule) {
  TypeSystemClang ast("module_ast", HostInfo::GetTargetTriple());
  CompilerType basic_compiler_type = ast.GetBasicType(BasicType::eBasicTypeInt);
  CompilerType enum_type = ast.CreateEnumerationType(
      "my_enum", ast.GetTranslationUnitDecl(), OptionalClangModuleID(100),
      Declaration(), basic_compiler_type, false);
  auto *ed = TypeSystemClang::GetAsEnumDecl(enum_type);
  EXPECT_FALSE(!ed);
  EXPECT_EQ(ed->getOwningModuleID(), 100u);

  CompilerType record_type = ast.CreateRecordType(
      nullptr, OptionalClangModuleID(200), lldb::eAccessPublic, "FooRecord",
      clang::TTK_Struct, lldb::eLanguageTypeC_plus_plus, nullptr);
  auto *rd = TypeSystemClang::GetAsRecordDecl(record_type);
  EXPECT_FALSE(!rd);
  EXPECT_EQ(rd->getOwningModuleID(), 200u);

  CompilerType class_type =
      ast.CreateObjCClass("objc_class", ast.GetTranslationUnitDecl(),
                          OptionalClangModuleID(300), false, false);
  auto *cd = TypeSystemClang::GetAsObjCInterfaceDecl(class_type);
  EXPECT_FALSE(!cd);
  EXPECT_EQ(cd->getOwningModuleID(), 300u);
}

TEST_F(TestTypeSystemClang, TestIsClangType) {
  clang::ASTContext &context = m_ast->getASTContext();
  lldb::opaque_compiler_type_t bool_ctype =
      TypeSystemClang::GetOpaqueCompilerType(&context, lldb::eBasicTypeBool);
  CompilerType bool_type(m_ast.get(), bool_ctype);
  CompilerType record_type = m_ast->CreateRecordType(
      nullptr, OptionalClangModuleID(100), lldb::eAccessPublic, "FooRecord",
      clang::TTK_Struct, lldb::eLanguageTypeC_plus_plus, nullptr);
  // Clang builtin type and record type should pass
  EXPECT_TRUE(ClangUtil::IsClangType(bool_type));
  EXPECT_TRUE(ClangUtil::IsClangType(record_type));

  // Default constructed type should fail
  EXPECT_FALSE(ClangUtil::IsClangType(CompilerType()));
}

TEST_F(TestTypeSystemClang, TestRemoveFastQualifiers) {
  CompilerType record_type = m_ast->CreateRecordType(
      nullptr, OptionalClangModuleID(), lldb::eAccessPublic, "FooRecord",
      clang::TTK_Struct, lldb::eLanguageTypeC_plus_plus, nullptr);
  QualType qt;

  qt = ClangUtil::GetQualType(record_type);
  EXPECT_EQ(0u, qt.getLocalFastQualifiers());
  record_type = record_type.AddConstModifier();
  record_type = record_type.AddVolatileModifier();
  record_type = record_type.AddRestrictModifier();
  qt = ClangUtil::GetQualType(record_type);
  EXPECT_NE(0u, qt.getLocalFastQualifiers());
  record_type = ClangUtil::RemoveFastQualifiers(record_type);
  qt = ClangUtil::GetQualType(record_type);
  EXPECT_EQ(0u, qt.getLocalFastQualifiers());
}

TEST_F(TestTypeSystemClang, TestConvertAccessTypeToAccessSpecifier) {
  EXPECT_EQ(AS_none,
            TypeSystemClang::ConvertAccessTypeToAccessSpecifier(eAccessNone));
  EXPECT_EQ(AS_none, TypeSystemClang::ConvertAccessTypeToAccessSpecifier(
                         eAccessPackage));
  EXPECT_EQ(AS_public,
            TypeSystemClang::ConvertAccessTypeToAccessSpecifier(eAccessPublic));
  EXPECT_EQ(AS_private, TypeSystemClang::ConvertAccessTypeToAccessSpecifier(
                            eAccessPrivate));
  EXPECT_EQ(AS_protected, TypeSystemClang::ConvertAccessTypeToAccessSpecifier(
                              eAccessProtected));
}

TEST_F(TestTypeSystemClang, TestUnifyAccessSpecifiers) {
  // Unifying two of the same type should return the same type
  EXPECT_EQ(AS_public,
            TypeSystemClang::UnifyAccessSpecifiers(AS_public, AS_public));
  EXPECT_EQ(AS_private,
            TypeSystemClang::UnifyAccessSpecifiers(AS_private, AS_private));
  EXPECT_EQ(AS_protected,
            TypeSystemClang::UnifyAccessSpecifiers(AS_protected, AS_protected));

  // Otherwise the result should be the strictest of the two.
  EXPECT_EQ(AS_private,
            TypeSystemClang::UnifyAccessSpecifiers(AS_private, AS_public));
  EXPECT_EQ(AS_private,
            TypeSystemClang::UnifyAccessSpecifiers(AS_private, AS_protected));
  EXPECT_EQ(AS_private,
            TypeSystemClang::UnifyAccessSpecifiers(AS_public, AS_private));
  EXPECT_EQ(AS_private,
            TypeSystemClang::UnifyAccessSpecifiers(AS_protected, AS_private));
  EXPECT_EQ(AS_protected,
            TypeSystemClang::UnifyAccessSpecifiers(AS_protected, AS_public));
  EXPECT_EQ(AS_protected,
            TypeSystemClang::UnifyAccessSpecifiers(AS_public, AS_protected));

  // None is stricter than everything (by convention)
  EXPECT_EQ(AS_none,
            TypeSystemClang::UnifyAccessSpecifiers(AS_none, AS_public));
  EXPECT_EQ(AS_none,
            TypeSystemClang::UnifyAccessSpecifiers(AS_none, AS_protected));
  EXPECT_EQ(AS_none,
            TypeSystemClang::UnifyAccessSpecifiers(AS_none, AS_private));
  EXPECT_EQ(AS_none,
            TypeSystemClang::UnifyAccessSpecifiers(AS_public, AS_none));
  EXPECT_EQ(AS_none,
            TypeSystemClang::UnifyAccessSpecifiers(AS_protected, AS_none));
  EXPECT_EQ(AS_none,
            TypeSystemClang::UnifyAccessSpecifiers(AS_private, AS_none));
}

TEST_F(TestTypeSystemClang, TestRecordHasFields) {
  CompilerType int_type = m_ast->GetBasicType(eBasicTypeInt);

  // Test that a record with no fields returns false
  CompilerType empty_base = m_ast->CreateRecordType(
      nullptr, OptionalClangModuleID(), lldb::eAccessPublic, "EmptyBase",
      clang::TTK_Struct, lldb::eLanguageTypeC_plus_plus, nullptr);
  TypeSystemClang::StartTagDeclarationDefinition(empty_base);
  TypeSystemClang::CompleteTagDeclarationDefinition(empty_base);

  RecordDecl *empty_base_decl = TypeSystemClang::GetAsRecordDecl(empty_base);
  EXPECT_NE(nullptr, empty_base_decl);
  EXPECT_FALSE(TypeSystemClang::RecordHasFields(empty_base_decl));

  // Test that a record with direct fields returns true
  CompilerType non_empty_base = m_ast->CreateRecordType(
      nullptr, OptionalClangModuleID(), lldb::eAccessPublic, "NonEmptyBase",
      clang::TTK_Struct, lldb::eLanguageTypeC_plus_plus, nullptr);
  TypeSystemClang::StartTagDeclarationDefinition(non_empty_base);
  FieldDecl *non_empty_base_field_decl = m_ast->AddFieldToRecordType(
      non_empty_base, "MyField", int_type, eAccessPublic, 0);
  TypeSystemClang::CompleteTagDeclarationDefinition(non_empty_base);
  RecordDecl *non_empty_base_decl =
      TypeSystemClang::GetAsRecordDecl(non_empty_base);
  EXPECT_NE(nullptr, non_empty_base_decl);
  EXPECT_NE(nullptr, non_empty_base_field_decl);
  EXPECT_TRUE(TypeSystemClang::RecordHasFields(non_empty_base_decl));

  std::vector<std::unique_ptr<clang::CXXBaseSpecifier>> bases;

  // Test that a record with no direct fields, but fields in a base returns true
  CompilerType empty_derived = m_ast->CreateRecordType(
      nullptr, OptionalClangModuleID(), lldb::eAccessPublic, "EmptyDerived",
      clang::TTK_Struct, lldb::eLanguageTypeC_plus_plus, nullptr);
  TypeSystemClang::StartTagDeclarationDefinition(empty_derived);
  std::unique_ptr<clang::CXXBaseSpecifier> non_empty_base_spec =
      m_ast->CreateBaseClassSpecifier(non_empty_base.GetOpaqueQualType(),
                                      lldb::eAccessPublic, false, false);
  bases.push_back(std::move(non_empty_base_spec));
  bool result = m_ast->TransferBaseClasses(empty_derived.GetOpaqueQualType(),
                                           std::move(bases));
  TypeSystemClang::CompleteTagDeclarationDefinition(empty_derived);
  EXPECT_TRUE(result);
  CXXRecordDecl *empty_derived_non_empty_base_cxx_decl =
      m_ast->GetAsCXXRecordDecl(empty_derived.GetOpaqueQualType());
  RecordDecl *empty_derived_non_empty_base_decl =
      TypeSystemClang::GetAsRecordDecl(empty_derived);
  EXPECT_EQ(1u, TypeSystemClang::GetNumBaseClasses(
                    empty_derived_non_empty_base_cxx_decl, false));
  EXPECT_TRUE(
      TypeSystemClang::RecordHasFields(empty_derived_non_empty_base_decl));

  // Test that a record with no direct fields, but fields in a virtual base
  // returns true
  CompilerType empty_derived2 = m_ast->CreateRecordType(
      nullptr, OptionalClangModuleID(), lldb::eAccessPublic, "EmptyDerived2",
      clang::TTK_Struct, lldb::eLanguageTypeC_plus_plus, nullptr);
  TypeSystemClang::StartTagDeclarationDefinition(empty_derived2);
  std::unique_ptr<CXXBaseSpecifier> non_empty_vbase_spec =
      m_ast->CreateBaseClassSpecifier(non_empty_base.GetOpaqueQualType(),
                                      lldb::eAccessPublic, true, false);
  bases.push_back(std::move(non_empty_vbase_spec));
  result = m_ast->TransferBaseClasses(empty_derived2.GetOpaqueQualType(),
                                      std::move(bases));
  TypeSystemClang::CompleteTagDeclarationDefinition(empty_derived2);
  EXPECT_TRUE(result);
  CXXRecordDecl *empty_derived_non_empty_vbase_cxx_decl =
      m_ast->GetAsCXXRecordDecl(empty_derived2.GetOpaqueQualType());
  RecordDecl *empty_derived_non_empty_vbase_decl =
      TypeSystemClang::GetAsRecordDecl(empty_derived2);
  EXPECT_EQ(1u, TypeSystemClang::GetNumBaseClasses(
                    empty_derived_non_empty_vbase_cxx_decl, false));
  EXPECT_TRUE(
      TypeSystemClang::RecordHasFields(empty_derived_non_empty_vbase_decl));
}

TEST_F(TestTypeSystemClang, TemplateArguments) {
  TypeSystemClang::TemplateParameterInfos infos;
  infos.names.push_back("T");
  infos.args.push_back(TemplateArgument(m_ast->getASTContext().IntTy));
  infos.names.push_back("I");
  llvm::APSInt arg(llvm::APInt(8, 47));
  infos.args.push_back(TemplateArgument(m_ast->getASTContext(), arg,
                                        m_ast->getASTContext().IntTy));

  // template<typename T, int I> struct foo;
  ClassTemplateDecl *decl = m_ast->CreateClassTemplateDecl(
      m_ast->GetTranslationUnitDecl(), OptionalClangModuleID(), eAccessPublic,
      "foo", TTK_Struct, infos);
  ASSERT_NE(decl, nullptr);

  // foo<int, 47>
  ClassTemplateSpecializationDecl *spec_decl =
      m_ast->CreateClassTemplateSpecializationDecl(
          m_ast->GetTranslationUnitDecl(), OptionalClangModuleID(), decl,
          TTK_Struct, infos);
  ASSERT_NE(spec_decl, nullptr);
  CompilerType type = m_ast->CreateClassTemplateSpecializationType(spec_decl);
  ASSERT_TRUE(type);
  m_ast->StartTagDeclarationDefinition(type);
  m_ast->CompleteTagDeclarationDefinition(type);

  // typedef foo<int, 47> foo_def;
  CompilerType typedef_type = type.CreateTypedef(
      "foo_def", m_ast->CreateDeclContext(m_ast->GetTranslationUnitDecl()), 0);

  CompilerType auto_type(
      m_ast.get(),
      m_ast->getASTContext()
          .getAutoType(ClangUtil::GetCanonicalQualType(typedef_type),
                       clang::AutoTypeKeyword::Auto, false)
          .getAsOpaquePtr());

  CompilerType int_type(m_ast.get(),
                        m_ast->getASTContext().IntTy.getAsOpaquePtr());
  for (CompilerType t : {type, typedef_type, auto_type}) {
    SCOPED_TRACE(t.GetTypeName().AsCString());

    EXPECT_EQ(m_ast->GetTemplateArgumentKind(t.GetOpaqueQualType(), 0),
              eTemplateArgumentKindType);
    EXPECT_EQ(m_ast->GetTypeTemplateArgument(t.GetOpaqueQualType(), 0),
              int_type);
    EXPECT_EQ(llvm::None,
              m_ast->GetIntegralTemplateArgument(t.GetOpaqueQualType(), 0));

    EXPECT_EQ(m_ast->GetTemplateArgumentKind(t.GetOpaqueQualType(), 1),
              eTemplateArgumentKindIntegral);
    EXPECT_EQ(m_ast->GetTypeTemplateArgument(t.GetOpaqueQualType(), 1),
              CompilerType());
    auto result = m_ast->GetIntegralTemplateArgument(t.GetOpaqueQualType(), 1);
    ASSERT_NE(llvm::None, result);
    EXPECT_EQ(arg, result->value);
    EXPECT_EQ(int_type, result->type);
  }
}

class TestCreateClassTemplateDecl : public TestTypeSystemClang {
protected:
  /// The class templates created so far by the Expect* functions below.
  llvm::DenseSet<ClassTemplateDecl *> m_created_templates;

  /// Utility function for creating a class template.
  ClassTemplateDecl *
  CreateClassTemplate(const TypeSystemClang::TemplateParameterInfos &infos) {
    ClassTemplateDecl *decl = m_ast->CreateClassTemplateDecl(
        m_ast->GetTranslationUnitDecl(), OptionalClangModuleID(), eAccessPublic,
        "foo", TTK_Struct, infos);
    return decl;
  }

  /// Creates a new class template with the given template parameters.
  /// Asserts that a new ClassTemplateDecl is created.
  /// \param description The gtest scope string that should describe the input.
  /// \param infos The template parameters that the class template should have.
  /// \returns The created ClassTemplateDecl.
  ClassTemplateDecl *
  ExpectNewTemplate(std::string description,
                    const TypeSystemClang::TemplateParameterInfos &infos) {
    SCOPED_TRACE(description);
    ClassTemplateDecl *first_template = CreateClassTemplate(infos);
    // A new template should have been created.
    EXPECT_FALSE(m_created_templates.contains(first_template))
        << "Didn't create new class template but reused this existing decl:\n"
        << ClangUtil::DumpDecl(first_template);
    m_created_templates.insert(first_template);

    // Creating a new template with the same arguments should always return
    // the template created above.
    ClassTemplateDecl *second_template = CreateClassTemplate(infos);
    EXPECT_EQ(first_template, second_template)
        << "Second attempt to create class template didn't reuse first decl:\n"
        << ClangUtil::DumpDecl(first_template) << "\nInstead created/reused:\n"
        << ClangUtil::DumpDecl(second_template);
    return first_template;
  }

  /// Tries to create a new class template but asserts that an existing class
  /// template in the current AST is reused (in contract so a new class
  /// template being created).
  /// \param description The gtest scope string that should describe the input.
  /// \param infos The template parameters that the class template should have.
  void
  ExpectReusedTemplate(std::string description,
                       const TypeSystemClang::TemplateParameterInfos &infos,
                       ClassTemplateDecl *expected) {
    SCOPED_TRACE(description);
    ClassTemplateDecl *td = CreateClassTemplate(infos);
    EXPECT_EQ(td, expected)
        << "Created/reused class template is:\n"
        << ClangUtil::DumpDecl(td) << "\nExpected to reuse:\n"
        << ClangUtil::DumpDecl(expected);
  }
};

TEST_F(TestCreateClassTemplateDecl, FindExistingTemplates) {
  // This tests the logic in TypeSystemClang::CreateClassTemplateDecl that
  // decides whether an existing ClassTemplateDecl in the AST can be reused.
  // The behaviour should follow the C++ rules for redeclaring templates
  // (e.g., parameter names can be changed/omitted.)

  // This describes a class template *instantiation* from which we will infer
  // the structure of the class template.
  TypeSystemClang::TemplateParameterInfos infos;

  // Test an empty template parameter list: <>
  ExpectNewTemplate("<>", infos);

  // Test that <typename T> with T = int creates a new template.
  infos.names = {"T"};
  infos.args = {TemplateArgument(m_ast->getASTContext().IntTy)};
  ClassTemplateDecl *single_type_arg = ExpectNewTemplate("<typename T>", infos);

  // Test that changing the parameter name doesn't create a new class template.
  infos.names = {"A"};
  ExpectReusedTemplate("<typename A> (A = int)", infos, single_type_arg);

  // Test that changing the used type doesn't create a new class template.
  infos.args = {TemplateArgument(m_ast->getASTContext().FloatTy)};
  ExpectReusedTemplate("<typename A> (A = float)", infos, single_type_arg);

  // Test that <typename A, signed char I> creates a new template with A = int
  // and I = 47;
  infos.names.push_back("I");
  infos.args.push_back(TemplateArgument(m_ast->getASTContext(),
                                        llvm::APSInt(llvm::APInt(8, 47)),
                                        m_ast->getASTContext().SignedCharTy));
  ClassTemplateDecl *type_and_char_value =
      ExpectNewTemplate("<typename A, signed char I> (I = 47)", infos);

  // Change the value of the I parameter to 123. The previously created
  // class template should still be reused.
  infos.args.pop_back();
  infos.args.push_back(TemplateArgument(m_ast->getASTContext(),
                                        llvm::APSInt(llvm::APInt(8, 123)),
                                        m_ast->getASTContext().SignedCharTy));
  ExpectReusedTemplate("<typename A, signed char I> (I = 123)", infos,
                       type_and_char_value);

  // Change the type of the I parameter to int so we have <typename A, int I>.
  // The class template from above can't be reused.
  infos.args.pop_back();
  infos.args.push_back(TemplateArgument(m_ast->getASTContext(),
                                        llvm::APSInt(llvm::APInt(32, 47)),
                                        m_ast->getASTContext().IntTy));
  ExpectNewTemplate("<typename A, int I> (I = 123)", infos);

  // Test a second type parameter will also cause a new template to be created.
  // We now have <typename A, int I, typename B>.
  infos.names.push_back("B");
  infos.args.push_back(TemplateArgument(m_ast->getASTContext().IntTy));
  ClassTemplateDecl *type_and_char_value_and_type =
      ExpectNewTemplate("<typename A, int I, typename B>", infos);

  // Remove all the names from the parameters which shouldn't influence the
  // way the templates get merged.
  infos.names = {"", "", ""};
  ExpectReusedTemplate("<typename, int, typename>", infos,
                       type_and_char_value_and_type);
}

TEST_F(TestCreateClassTemplateDecl, FindExistingTemplatesWithParameterPack) {
  // The same as FindExistingTemplates but for templates with parameter packs.

  TypeSystemClang::TemplateParameterInfos infos;
  infos.packed_args =
      std::make_unique<TypeSystemClang::TemplateParameterInfos>();
  infos.packed_args->names = {"", ""};
  infos.packed_args->args = {TemplateArgument(m_ast->getASTContext().IntTy),
                             TemplateArgument(m_ast->getASTContext().IntTy)};
  ClassTemplateDecl *type_pack =
      ExpectNewTemplate("<typename ...> (int, int)", infos);

  // Special case: An instantiation for a parameter pack with no values fits
  // to whatever class template we find. There isn't enough information to
  // do an actual comparison here.
  infos.packed_args =
      std::make_unique<TypeSystemClang::TemplateParameterInfos>();
  ExpectReusedTemplate("<...> (no values in pack)", infos, type_pack);

  // Change the type content of pack type values.
  infos.packed_args->names = {"", ""};
  infos.packed_args->args = {TemplateArgument(m_ast->getASTContext().IntTy),
                             TemplateArgument(m_ast->getASTContext().LongTy)};
  ExpectReusedTemplate("<typename ...> (int, long)", infos, type_pack);

  // Change the number of pack values.
  infos.packed_args->args = {TemplateArgument(m_ast->getASTContext().IntTy)};
  ExpectReusedTemplate("<typename ...> (int)", infos, type_pack);

  // The names of the pack values shouldn't matter.
  infos.packed_args->names = {"A", "B"};
  ExpectReusedTemplate("<typename ...> (int)", infos, type_pack);

  // Changing the kind of template argument will create a new template.
  infos.packed_args->args = {TemplateArgument(m_ast->getASTContext(),
                                              llvm::APSInt(llvm::APInt(32, 1)),
                                              m_ast->getASTContext().IntTy)};
  ClassTemplateDecl *int_pack = ExpectNewTemplate("<int ...> (int = 1)", infos);

  // Changing the value of integral parameters will not create a new template.
  infos.packed_args->args = {TemplateArgument(
      m_ast->getASTContext(), llvm::APSInt(llvm::APInt(32, 123)),
      m_ast->getASTContext().IntTy)};
  ExpectReusedTemplate("<int ...> (int = 123)", infos, int_pack);

  // Changing the integral type will create a new template.
  infos.packed_args->args = {TemplateArgument(m_ast->getASTContext(),
                                              llvm::APSInt(llvm::APInt(64, 1)),
                                              m_ast->getASTContext().LongTy)};
  ExpectNewTemplate("<long ...> (long = 1)", infos);

  // Prependinding a non-pack parameter will create a new template.
  infos.names = {"T"};
  infos.args = {TemplateArgument(m_ast->getASTContext().IntTy)};
  ExpectNewTemplate("<typename T, long...> (T = int, long = 1)", infos);
}

TEST_F(TestTypeSystemClang, OnlyPackName) {
  TypeSystemClang::TemplateParameterInfos infos;
  infos.pack_name = "A";
  EXPECT_FALSE(infos.IsValid());
}

static QualType makeConstInt(clang::ASTContext &ctxt) {
  QualType result(ctxt.IntTy);
  result.addConst();
  return result;
}

TEST_F(TestTypeSystemClang, TestGetTypeClassDeclType) {
  clang::ASTContext &ctxt = m_ast->getASTContext();
  auto *nullptr_expr = new (ctxt) CXXNullPtrLiteralExpr(ctxt.NullPtrTy, SourceLocation());
  QualType t = ctxt.getDecltypeType(nullptr_expr, makeConstInt(ctxt));
  EXPECT_EQ(lldb::eTypeClassBuiltin, m_ast->GetTypeClass(t.getAsOpaquePtr()));
}

TEST_F(TestTypeSystemClang, TestGetTypeClassTypeOf) {
  clang::ASTContext &ctxt = m_ast->getASTContext();
  QualType t = ctxt.getTypeOfType(makeConstInt(ctxt));
  EXPECT_EQ(lldb::eTypeClassBuiltin, m_ast->GetTypeClass(t.getAsOpaquePtr()));
}

TEST_F(TestTypeSystemClang, TestGetTypeClassTypeOfExpr) {
  clang::ASTContext &ctxt = m_ast->getASTContext();
  auto *nullptr_expr = new (ctxt) CXXNullPtrLiteralExpr(ctxt.NullPtrTy, SourceLocation());
  QualType t = ctxt.getTypeOfExprType(nullptr_expr);
  EXPECT_EQ(lldb::eTypeClassBuiltin, m_ast->GetTypeClass(t.getAsOpaquePtr()));
}

TEST_F(TestTypeSystemClang, TestGetTypeClassNested) {
  clang::ASTContext &ctxt = m_ast->getASTContext();
  QualType t_base = ctxt.getTypeOfType(makeConstInt(ctxt));
  QualType t = ctxt.getTypeOfType(t_base);
  EXPECT_EQ(lldb::eTypeClassBuiltin, m_ast->GetTypeClass(t.getAsOpaquePtr()));
}

TEST_F(TestTypeSystemClang, TestFunctionTemplateConstruction) {
  // Tests creating a function template.

  CompilerType int_type = m_ast->GetBasicType(lldb::eBasicTypeInt);
  clang::TranslationUnitDecl *TU = m_ast->GetTranslationUnitDecl();

  // Prepare the declarations/types we need for the template.
  CompilerType clang_type =
      m_ast->CreateFunctionType(int_type, nullptr, 0U, false, 0U);
  FunctionDecl *func = m_ast->CreateFunctionDeclaration(
      TU, OptionalClangModuleID(), "foo", clang_type, StorageClass::SC_None,
      false);
  TypeSystemClang::TemplateParameterInfos empty_params;

  // Create the actual function template.
  clang::FunctionTemplateDecl *func_template =
      m_ast->CreateFunctionTemplateDecl(TU, OptionalClangModuleID(), func,
                                        empty_params);

  EXPECT_EQ(TU, func_template->getDeclContext());
  EXPECT_EQ("foo", func_template->getName());
  EXPECT_EQ(clang::AccessSpecifier::AS_none, func_template->getAccess());
}

TEST_F(TestTypeSystemClang, TestFunctionTemplateInRecordConstruction) {
  // Tests creating a function template inside a record.

  CompilerType int_type = m_ast->GetBasicType(lldb::eBasicTypeInt);
  clang::TranslationUnitDecl *TU = m_ast->GetTranslationUnitDecl();

  // Create a record we can put the function template int.
  CompilerType record_type =
      clang_utils::createRecordWithField(*m_ast, "record", int_type, "field");
  clang::TagDecl *record = ClangUtil::GetAsTagDecl(record_type);

  // Prepare the declarations/types we need for the template.
  CompilerType clang_type =
      m_ast->CreateFunctionType(int_type, nullptr, 0U, false, 0U);
  // We create the FunctionDecl for the template in the TU DeclContext because:
  // 1. FunctionDecls can't be in a Record (only CXXMethodDecls can).
  // 2. It is mirroring the behavior of DWARFASTParserClang::ParseSubroutine.
  FunctionDecl *func = m_ast->CreateFunctionDeclaration(
      TU, OptionalClangModuleID(), "foo", clang_type, StorageClass::SC_None,
      false);
  TypeSystemClang::TemplateParameterInfos empty_params;

  // Create the actual function template.
  clang::FunctionTemplateDecl *func_template =
      m_ast->CreateFunctionTemplateDecl(record, OptionalClangModuleID(), func,
                                        empty_params);

  EXPECT_EQ(record, func_template->getDeclContext());
  EXPECT_EQ("foo", func_template->getName());
  EXPECT_EQ(clang::AccessSpecifier::AS_public, func_template->getAccess());
}

TEST_F(TestTypeSystemClang, TestDeletingImplicitCopyCstrDueToMoveCStr) {
  // We need to simulate this behavior in our AST that we construct as we don't
  // have a Sema instance that can do this for us:
  // C++11 [class.copy]p7, p18:
  //  If the class definition declares a move constructor or move assignment
  //  operator, an implicitly declared copy constructor or copy assignment
  //  operator is defined as deleted.

  // Create a record and start defining it.
  llvm::StringRef class_name = "S";
  CompilerType t = clang_utils::createRecord(*m_ast, class_name);
  m_ast->StartTagDeclarationDefinition(t);

  // Create a move constructor that will delete the implicit copy constructor.
  CompilerType return_type = m_ast->GetBasicType(lldb::eBasicTypeVoid);
  CompilerType param_type = t.GetRValueReferenceType();
  CompilerType function_type =
      m_ast->CreateFunctionType(return_type, &param_type, /*num_params*/ 1,
                                /*variadic=*/false, /*quals*/ 0U);
  bool is_virtual = false;
  bool is_static = false;
  bool is_inline = false;
  bool is_explicit = true;
  bool is_attr_used = false;
  bool is_artificial = false;
  m_ast->AddMethodToCXXRecordType(
      t.GetOpaqueQualType(), class_name, nullptr, function_type,
      lldb::AccessType::eAccessPublic, is_virtual, is_static, is_inline,
      is_explicit, is_attr_used, is_artificial);

  // Complete the definition and check the created record.
  m_ast->CompleteTagDeclarationDefinition(t);
  auto *record = llvm::cast<CXXRecordDecl>(ClangUtil::GetAsTagDecl(t));
  // We can't call defaultedCopyConstructorIsDeleted() as this requires that
  // the Decl passes through Sema which will actually compute this field.
  // Instead we check that there is no copy constructor declared by the user
  // which only leaves a non-deleted defaulted copy constructor as an option
  // that our record will have no simple copy constructor.
  EXPECT_FALSE(record->hasUserDeclaredCopyConstructor());
  EXPECT_FALSE(record->hasSimpleCopyConstructor());
}

TEST_F(TestTypeSystemClang, TestNotDeletingUserCopyCstrDueToMoveCStr) {
  // Tests that we don't delete the a user-defined copy constructor when
  // a move constructor is provided.
  // See also the TestDeletingImplicitCopyCstrDueToMoveCStr test.
  llvm::StringRef class_name = "S";
  CompilerType t = clang_utils::createRecord(*m_ast, class_name);
  m_ast->StartTagDeclarationDefinition(t);

  CompilerType return_type = m_ast->GetBasicType(lldb::eBasicTypeVoid);
  bool is_virtual = false;
  bool is_static = false;
  bool is_inline = false;
  bool is_explicit = true;
  bool is_attr_used = false;
  bool is_artificial = false;
  // Create a move constructor.
  {
    CompilerType param_type = t.GetRValueReferenceType();
    CompilerType function_type =
        m_ast->CreateFunctionType(return_type, &param_type, /*num_params*/ 1,
                                  /*variadic=*/false, /*quals*/ 0U);
    m_ast->AddMethodToCXXRecordType(
        t.GetOpaqueQualType(), class_name, nullptr, function_type,
        lldb::AccessType::eAccessPublic, is_virtual, is_static, is_inline,
        is_explicit, is_attr_used, is_artificial);
  }
  // Create a copy constructor.
  {
    CompilerType param_type = t.GetLValueReferenceType().AddConstModifier();
    CompilerType function_type =
        m_ast->CreateFunctionType(return_type, &param_type, /*num_params*/ 1,
                                  /*variadic=*/false, /*quals*/ 0U);
    m_ast->AddMethodToCXXRecordType(
        t.GetOpaqueQualType(), class_name, nullptr, function_type,
        lldb::AccessType::eAccessPublic, is_virtual, is_static, is_inline,
        is_explicit, is_attr_used, is_artificial);
  }

  // Complete the definition and check the created record.
  m_ast->CompleteTagDeclarationDefinition(t);
  auto *record = llvm::cast<CXXRecordDecl>(ClangUtil::GetAsTagDecl(t));
  EXPECT_TRUE(record->hasUserDeclaredCopyConstructor());
}

TEST_F(TestTypeSystemClang, AddMethodToObjCObjectType) {
  // Create an interface decl and mark it as having external storage.
  CompilerType c = m_ast->CreateObjCClass("A", m_ast->GetTranslationUnitDecl(),
                                          OptionalClangModuleID(),
                                          /*IsForwardDecl*/ false,
                                          /*IsInternal*/ false);
  ObjCInterfaceDecl *interface = m_ast->GetAsObjCInterfaceDecl(c);
  m_ast->SetHasExternalStorage(c.GetOpaqueQualType(), true);
  EXPECT_TRUE(interface->hasExternalLexicalStorage());

  // Add a method to the interface.
  std::vector<CompilerType> args;
  CompilerType func_type =
      m_ast->CreateFunctionType(m_ast->GetBasicType(lldb::eBasicTypeInt),
                                args.data(), args.size(), /*variadic*/ false,
                                /*quals*/ 0, clang::CallingConv::CC_C);
  bool variadic = false;
  bool artificial = false;
  bool objc_direct = false;
  clang::ObjCMethodDecl *method = TypeSystemClang::AddMethodToObjCObjectType(
      c, "-[A foo]", func_type, lldb::eAccessPublic, artificial, variadic,
      objc_direct);
  ASSERT_NE(method, nullptr);

  // The interface decl should still have external lexical storage.
  EXPECT_TRUE(interface->hasExternalLexicalStorage());

  // Test some properties of the created ObjCMethodDecl.
  EXPECT_FALSE(method->isVariadic());
  EXPECT_TRUE(method->isImplicit());
  EXPECT_FALSE(method->isDirectMethod());
  EXPECT_EQ(method->getDeclName().getObjCSelector().getAsString(), "foo");
}

TEST_F(TestTypeSystemClang, GetFullyUnqualifiedType) {
  CompilerType bool_ = m_ast->GetBasicType(eBasicTypeBool);
  CompilerType cv_bool = bool_.AddConstModifier().AddVolatileModifier();

  // const volatile bool -> bool
  EXPECT_EQ(bool_, cv_bool.GetFullyUnqualifiedType());

  // const volatile bool[47] -> bool[47]
  EXPECT_EQ(bool_.GetArrayType(47),
            cv_bool.GetArrayType(47).GetFullyUnqualifiedType());

  // const volatile bool[47][42] -> bool[47][42]
  EXPECT_EQ(
      bool_.GetArrayType(42).GetArrayType(47),
      cv_bool.GetArrayType(42).GetArrayType(47).GetFullyUnqualifiedType());

  // const volatile bool * -> bool *
  EXPECT_EQ(bool_.GetPointerType(),
            cv_bool.GetPointerType().GetFullyUnqualifiedType());

  // const volatile bool *[47] -> bool *[47]
  EXPECT_EQ(
      bool_.GetPointerType().GetArrayType(47),
      cv_bool.GetPointerType().GetArrayType(47).GetFullyUnqualifiedType());
}

TEST(TestScratchTypeSystemClang, InferSubASTFromLangOpts) {
  LangOptions lang_opts;
  EXPECT_EQ(
      ScratchTypeSystemClang::DefaultAST,
      ScratchTypeSystemClang::InferIsolatedASTKindFromLangOpts(lang_opts));

  lang_opts.Modules = true;
  EXPECT_EQ(
      ScratchTypeSystemClang::IsolatedASTKind::CppModules,
      ScratchTypeSystemClang::InferIsolatedASTKindFromLangOpts(lang_opts));
}

TEST_F(TestTypeSystemClang, GetExeModuleWhenMissingSymbolFile) {
  CompilerType compiler_type = m_ast->GetBasicTypeFromAST(lldb::eBasicTypeInt);
  lldb_private::Type t(0, nullptr, ConstString("MyType"), llvm::None, nullptr,
                       0, {}, {}, compiler_type,
                       lldb_private::Type::ResolveState::Full);
  // Test that getting the execution module when no type system is present
  // is handled gracefully.
  ModuleSP module = t.GetExeModule();
  EXPECT_EQ(module.get(), nullptr);
}

