blob: 44a7eac3562f68b33c74999e408dc6a7bf6502af [file] [log] [blame]
//===--- GenProto.h - Swift IR generation for prototypes --------*- C++ -*-===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See http://swift.org/LICENSE.txt for license information
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
//
// This file provides the private interface to the protocol-emission code.
//
//===----------------------------------------------------------------------===//
#ifndef SWIFT_IRGEN_GENPROTO_H
#define SWIFT_IRGEN_GENPROTO_H
namespace llvm {
class Type;
}
namespace swift {
class CanType;
class FuncDecl;
class ProtocolConformance;
struct SILDeclRef;
class SILType;
class SILFunction;
namespace irgen {
class AbstractCallee;
class Address;
class Explosion;
class CallEmission;
class IRGenFunction;
class IRGenModule;
class ProtocolInfo;
class TypeInfo;
/// Extract the method pointer from an archetype's witness table
/// as a function value.
void emitWitnessMethodValue(IRGenFunction &IGF,
CanType baseTy,
SILDeclRef member,
ProtocolConformance *conformance,
Explosion &out);
/// Add the witness parameters necessary for calling a function with
/// the given generics clause.
void expandPolymorphicSignature(IRGenModule &IGM,
CanSILFunctionType type,
SmallVectorImpl<llvm::Type*> &types);
/// Return the number of trailing arguments necessary for calling a
/// witness method.
inline unsigned getTrailingWitnessSignatureLength(IRGenModule &IGM,
CanSILFunctionType type) {
return 1;
}
/// Add the trailing arguments necessary for calling a witness method.
void expandTrailingWitnessSignature(IRGenModule &IGM,
CanSILFunctionType type,
SmallVectorImpl<llvm::Type*> &types);
struct WitnessMetadata {
llvm::Value *SelfMetadata = nullptr;
};
/// Collect any required metadata for a witness method from the end
/// of the given parameter list.
void collectTrailingWitnessMetadata(IRGenFunction &IGF, SILFunction &fn,
Explosion &params,
WitnessMetadata &metadata);
using GetParameterFn = llvm::function_ref<llvm::Value*(unsigned)>;
/// In the prelude of a generic function, perform the bindings for a
/// generics clause.
///
/// \param witnessMetadata - can be omitted if the function is
/// definitely not a witness method
void emitPolymorphicParameters(IRGenFunction &IGF,
SILFunction &Fn,
Explosion &args,
WitnessMetadata *witnessMetadata,
const GetParameterFn &getParameter);
/// Perform the metadata bindings necessary to emit a generic value witness.
void emitPolymorphicParametersForGenericValueWitness(IRGenFunction &IGF,
NominalTypeDecl *ntd,
llvm::Value *selfMeta);
/// Add the trailing arguments necessary for calling a witness method.
void emitTrailingWitnessArguments(IRGenFunction &IGF,
WitnessMetadata &witnessMetadata,
Explosion &args);
/// When calling a polymorphic call, pass the arguments for the
/// generics clause.
void emitPolymorphicArguments(IRGenFunction &IGF,
CanSILFunctionType origType,
CanSILFunctionType substType,
ArrayRef<Substitution> subs,
WitnessMetadata *witnessMetadata,
Explosion &args);
/// True if a type has a generic-parameter-dependent value witness table.
/// Currently, this is true if the size and/or alignment of the type is
/// dependent on its generic parameters.
bool hasDependentValueWitnessTable(IRGenModule &IGM, CanType ty);
/// Emit a value-witness table for the given type, which is assumed
/// to be non-dependent.
llvm::Constant *emitValueWitnessTable(IRGenModule &IGM, CanType type);
/// Emit the elements of a dependent value witness table template into a
/// vector.
void emitDependentValueWitnessTablePattern(IRGenModule &IGM,
CanType abstractType,
SmallVectorImpl<llvm::Constant*> &fields);
/// Emit references to the witness tables for the substituted type
/// in the given substitution.
void emitWitnessTableRefs(IRGenFunction &IGF, const Substitution &sub,
SmallVectorImpl<llvm::Value *> &out);
/// Emit a witness table reference.
llvm::Value *emitWitnessTableRef(IRGenFunction &IGF,
CanType srcType,
const TypeInfo &srcTI,
ProtocolDecl *proto,
const ProtocolInfo &protoI,
ProtocolConformance *conformance);
/// An entry in a list of known protocols.
class ProtocolEntry {
ProtocolDecl *Protocol;
const ProtocolInfo &Impl;
public:
explicit ProtocolEntry(ProtocolDecl *proto, const ProtocolInfo &impl)
: Protocol(proto), Impl(impl) {}
ProtocolDecl *getProtocol() const { return Protocol; }
const ProtocolInfo &getInfo() const { return Impl; }
};
using GetWitnessTableFn =
llvm::function_ref<llvm::Value*(unsigned originIndex)>;
llvm::Value *emitImpliedWitnessTableRef(IRGenFunction &IGF,
ArrayRef<ProtocolEntry> protos,
ProtocolDecl *target,
const GetWitnessTableFn &getWitnessTable);
/// Allocate space for a value in a value buffer.
Address emitAllocateBuffer(IRGenFunction &IGF, SILType valueType,
Address buffer);
/// Project to the address of a value in a value buffer.
Address emitProjectBuffer(IRGenFunction &IGF, SILType valueType,
Address buffer);
/// Deallocate space for a value in a value buffer.
void emitDeallocateBuffer(IRGenFunction &IGF, SILType valueType,
Address buffer);
} // end namespace irgen
} // end namespace swift
#endif