IRGenModule::IRGenModule(IRGenModuleDispatcher &dispatcher, SourceFile *SF, ASTContext &Context, llvm::LLVMContext &LLVMContext, IRGenOptions &Opts, StringRef ModuleName, const llvm::DataLayout &DataLayout, const llvm::Triple &Triple, llvm::TargetMachine *TargetMachine, SILModule *SILMod, StringRef OutputFilename) : Context(Context), Opts(Opts), ClangCodeGen(createClangCodeGenerator(Context, LLVMContext, Opts, ModuleName)), Module(*ClangCodeGen->GetModule()), LLVMContext(Module.getContext()), DataLayout(DataLayout), Triple(Triple), TargetMachine(TargetMachine), SILMod(SILMod), OutputFilename(OutputFilename), dispatcher(dispatcher), TargetInfo(SwiftTargetInfo::get(*this)), DebugInfo(0), ObjCInterop(Context.LangOpts.EnableObjCInterop), Types(*new TypeConverter(*this)) { dispatcher.addGenModule(SF, this); VoidTy = llvm::Type::getVoidTy(getLLVMContext()); Int1Ty = llvm::Type::getInt1Ty(getLLVMContext()); Int8Ty = llvm::Type::getInt8Ty(getLLVMContext()); Int16Ty = llvm::Type::getInt16Ty(getLLVMContext()); Int32Ty = llvm::Type::getInt32Ty(getLLVMContext()); Int64Ty = llvm::Type::getInt64Ty(getLLVMContext()); Int8PtrTy = llvm::Type::getInt8PtrTy(getLLVMContext()); Int8PtrPtrTy = Int8PtrTy->getPointerTo(0); SizeTy = DataLayout.getIntPtrType(getLLVMContext(), /*addrspace*/ 0); auto CI = static_cast<ClangImporter*>(&*Context.getClangModuleLoader()); assert(CI && "no clang module loader"); auto &clangASTContext = CI->getClangASTContext(); ObjCBoolTy = Int1Ty; if (clangASTContext.getTargetInfo().useSignedCharForObjCBool()) ObjCBoolTy = Int8Ty; RefCountedStructTy = llvm::StructType::create(getLLVMContext(), "swift.refcounted"); RefCountedPtrTy = RefCountedStructTy->getPointerTo(/*addrspace*/ 0); RefCountedNull = llvm::ConstantPointerNull::get(RefCountedPtrTy); // For now, native weak references are just a pointer. WeakReferencePtrTy = createStructPointerType(*this, "swift.weak", { RefCountedPtrTy }); // Native unowned references are just a pointer. UnownedReferencePtrTy = createStructPointerType(*this, "swift.unowned", { RefCountedPtrTy }); // A type metadata record is the structure pointed to by the canonical // address point of a type metadata. This is at least one word, and // potentially more than that, past the start of the actual global // structure. TypeMetadataStructTy = createStructType(*this, "swift.type", { MetadataKindTy // MetadataKind Kind; }); TypeMetadataPtrTy = TypeMetadataStructTy->getPointerTo(DefaultAS); // A protocol descriptor describes a protocol. It is not type metadata in // and of itself, but is referenced in the structure of existential type // metadata records. ProtocolDescriptorStructTy = createStructType(*this, "swift.protocol", { Int8PtrTy, // objc isa Int8PtrTy, // name Int8PtrTy, // inherited protocols Int8PtrTy, // required objc instance methods Int8PtrTy, // required objc class methods Int8PtrTy, // optional objc instance methods Int8PtrTy, // optional objc class methods Int8PtrTy, // objc properties Int32Ty, // size Int32Ty // flags }); ProtocolDescriptorPtrTy = ProtocolDescriptorStructTy->getPointerTo(); // A tuple type metadata record has a couple extra fields. auto tupleElementTy = createStructType(*this, "swift.tuple_element_type", { TypeMetadataPtrTy, // Metadata *Type; SizeTy // size_t Offset; }); TupleTypeMetadataPtrTy = createStructPointerType(*this, "swift.tuple_type", { TypeMetadataStructTy, // (base) SizeTy, // size_t NumElements; Int8PtrTy, // const char *Labels; llvm::ArrayType::get(tupleElementTy, 0) // Element Elements[]; }); // A full type metadata record is basically just an adjustment to the // address point of a type metadata. Resilience may cause // additional data to be laid out prior to this address point. FullTypeMetadataStructTy = createStructType(*this, "swift.full_type", { WitnessTablePtrTy, TypeMetadataStructTy }); FullTypeMetadataPtrTy = FullTypeMetadataStructTy->getPointerTo(DefaultAS); // A metadata pattern is a structure from which generic type // metadata are allocated. We leave this struct type intentionally // opaque, because the compiler basically never needs to access // anything from one. TypeMetadataPatternStructTy = llvm::StructType::create(getLLVMContext(), "swift.type_pattern"); TypeMetadataPatternPtrTy = TypeMetadataPatternStructTy->getPointerTo(DefaultAS); DeallocatingDtorTy = llvm::FunctionType::get(VoidTy, RefCountedPtrTy, false); llvm::Type *dtorPtrTy = DeallocatingDtorTy->getPointerTo(); // A full heap metadata is basically just an additional small prefix // on a full metadata, used for metadata corresponding to heap // allocations. FullHeapMetadataStructTy = createStructType(*this, "swift.full_heapmetadata", { dtorPtrTy, WitnessTablePtrTy, TypeMetadataStructTy }); FullHeapMetadataPtrTy = FullHeapMetadataStructTy->getPointerTo(DefaultAS); // A full box metadata is non-type heap metadata for a heap allocation of a // single value. The box tracks the offset to the value inside the box. FullBoxMetadataStructTy = createStructType(*this, "swift.full_boxmetadata", { dtorPtrTy, WitnessTablePtrTy, TypeMetadataStructTy, Int32Ty, }); FullBoxMetadataPtrTy = FullBoxMetadataStructTy->getPointerTo(DefaultAS); llvm::Type *refCountedElts[] = { TypeMetadataPtrTy, Int32Ty, Int32Ty }; RefCountedStructTy->setBody(refCountedElts); PtrSize = Size(DataLayout.getPointerSize(DefaultAS)); FunctionPairTy = createStructType(*this, "swift.function", { FunctionPtrTy, RefCountedPtrTy, }); OpaquePtrTy = llvm::StructType::create(LLVMContext, "swift.opaque") ->getPointerTo(DefaultAS); ProtocolConformanceRecordTy = createStructType(*this, "swift.protocol_conformance", { RelativeAddressTy, RelativeAddressTy, RelativeAddressTy, Int32Ty }); ProtocolConformanceRecordPtrTy = ProtocolConformanceRecordTy->getPointerTo(DefaultAS); FixedBufferTy = nullptr; for (unsigned i = 0; i != MaxNumValueWitnesses; ++i) ValueWitnessTys[i] = nullptr; ObjCPtrTy = llvm::StructType::create(getLLVMContext(), "objc_object") ->getPointerTo(DefaultAS); BridgeObjectPtrTy = llvm::StructType::create(getLLVMContext(), "swift.bridge") ->getPointerTo(DefaultAS); ObjCClassStructTy = llvm::StructType::create(LLVMContext, "objc_class"); ObjCClassPtrTy = ObjCClassStructTy->getPointerTo(DefaultAS); llvm::Type *objcClassElts[] = { ObjCClassPtrTy, ObjCClassPtrTy, OpaquePtrTy, OpaquePtrTy, IntPtrTy }; ObjCClassStructTy->setBody(objcClassElts); ObjCSuperStructTy = llvm::StructType::create(LLVMContext, "objc_super"); ObjCSuperPtrTy = ObjCSuperStructTy->getPointerTo(DefaultAS); llvm::Type *objcSuperElts[] = { ObjCPtrTy, ObjCClassPtrTy }; ObjCSuperStructTy->setBody(objcSuperElts); ObjCBlockStructTy = llvm::StructType::create(LLVMContext, "objc_block"); ObjCBlockPtrTy = ObjCBlockStructTy->getPointerTo(DefaultAS); llvm::Type *objcBlockElts[] = { ObjCClassPtrTy, // isa Int32Ty, // flags Int32Ty, // reserved FunctionPtrTy, // invoke function pointer Int8PtrTy, // TODO: block descriptor pointer. // We will probably need a struct type for that at some // point too. }; ObjCBlockStructTy->setBody(objcBlockElts); auto ErrorStructTy = llvm::StructType::create(LLVMContext, "swift.error"); // ErrorStruct is currently opaque to the compiler. ErrorPtrTy = ErrorStructTy->getPointerTo(DefaultAS); llvm::Type *openedErrorTriple[] = { OpaquePtrTy, TypeMetadataPtrTy, WitnessTablePtrTy, }; OpenedErrorTripleTy = llvm::StructType::get(getLLVMContext(), openedErrorTriple, /*packed*/ false); OpenedErrorTriplePtrTy = OpenedErrorTripleTy->getPointerTo(DefaultAS); InvariantMetadataID = LLVMContext.getMDKindID("invariant.load"); InvariantNode = llvm::MDNode::get(LLVMContext, {}); DereferenceableID = LLVMContext.getMDKindID("dereferenceable"); // TODO: use "tinycc" on platforms that support it RuntimeCC = llvm::CallingConv::C; ABITypes = new CodeGenABITypes(clangASTContext, Module); if (Opts.DebugInfoKind != IRGenDebugInfoKind::None) { DebugInfo = new IRGenDebugInfo(Opts, *CI, *this, Module, SF); } initClangTypeConverter(); }