//===-- 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(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);
}

