forked from swiftlang/swift
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathGenProto.h
173 lines (144 loc) · 6.73 KB
/
GenProto.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
//===--- 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 ¶ms,
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