18 using namespace clang;
19 using namespace CodeGen;
22 assert(Data &&
"dereferencing null future");
23 if (Data.is<llvm::Constant*>()) {
24 return Data.get<llvm::Constant*>()->
getType();
31 assert(Data &&
"abandoning null future");
39 assert(Data &&
"installing null future");
40 if (Data.is<llvm::Constant*>()) {
41 GV->setInitializer(Data.get<llvm::Constant*>());
44 assert(builder.Buffer.size() == 1);
45 builder.setGlobalInitializer(GV, builder.Buffer[0]);
46 builder.Buffer.clear();
52 ConstantInitBuilderBase::createFuture(llvm::Constant *initializer) {
53 assert(Buffer.empty() &&
"buffer not current empty");
54 Buffer.push_back(initializer);
61 assert(!builder->Frozen);
62 assert(builder->Buffer.size() == 1);
63 assert(builder->Buffer[0] !=
nullptr);
66 llvm::GlobalVariable *
67 ConstantInitBuilderBase::createGlobal(llvm::Constant *initializer,
68 const llvm::Twine &
name,
71 llvm::GlobalValue::LinkageTypes linkage,
72 unsigned addressSpace) {
73 auto GV =
new llvm::GlobalVariable(CGM.getModule(),
74 initializer->getType(),
80 llvm::GlobalValue::NotThreadLocal,
83 resolveSelfReferences(GV);
87 void ConstantInitBuilderBase::setGlobalInitializer(llvm::GlobalVariable *GV,
88 llvm::Constant *initializer){
89 GV->setInitializer(initializer);
91 if (!SelfReferences.empty())
92 resolveSelfReferences(GV);
95 void ConstantInitBuilderBase::resolveSelfReferences(llvm::GlobalVariable *GV) {
96 for (
auto &entry : SelfReferences) {
97 llvm::Constant *resolvedReference =
98 llvm::ConstantExpr::getInBoundsGetElementPtr(
99 GV->getValueType(), GV, entry.Indices);
100 auto dummy = entry.Dummy;
101 dummy->replaceAllUsesWith(resolvedReference);
102 dummy->eraseFromParent();
104 SelfReferences.clear();
107 void ConstantInitBuilderBase::abandon(
size_t newEnd) {
109 Buffer.erase(Buffer.begin() + newEnd, Buffer.end());
115 for (
auto &entry : SelfReferences) {
116 auto dummy = entry.Dummy;
117 dummy->replaceAllUsesWith(llvm::UndefValue::get(dummy->getType()));
118 dummy->eraseFromParent();
120 SelfReferences.clear();
125 add(Builder.CGM.getSize(size));
129 ConstantAggregateBuilderBase::getRelativeOffset(llvm::IntegerType *offsetType,
130 llvm::Constant *target) {
132 auto base = getAddrOfCurrentPosition(offsetType);
135 base = llvm::ConstantExpr::getPtrToInt(base, Builder.CGM.IntPtrTy);
136 target = llvm::ConstantExpr::getPtrToInt(target, Builder.CGM.IntPtrTy);
137 llvm::Constant *offset = llvm::ConstantExpr::getSub(target, base);
140 if (Builder.CGM.IntPtrTy != offsetType) {
141 offset = llvm::ConstantExpr::getTrunc(offset, offsetType);
152 new llvm::GlobalVariable(Builder.CGM.getModule(),
type,
true,
153 llvm::GlobalVariable::PrivateLinkage,
155 Builder.SelfReferences.emplace_back(dummy);
156 auto &entry = Builder.SelfReferences.back();
157 (void) getGEPIndicesToCurrentPosition(entry.Indices);
161 void ConstantAggregateBuilderBase::getGEPIndicesTo(
163 size_t position)
const {
170 assert(indices.empty());
171 indices.push_back(llvm::ConstantInt::get(Builder.CGM.Int32Ty, 0));
174 assert(position >=
Begin);
177 indices.push_back(llvm::ConstantInt::get(Builder.CGM.Int32Ty,
184 CharUnits offset = getNextOffsetFromGlobal();
187 auto position = addPlaceholder();
190 auto &layout = Builder.CGM.getDataLayout();
193 layout.getABITypeAlignment(type)));
196 CachedOffsetEnd = Builder.Buffer.size();
197 CachedOffsetFromGlobal = offset;
202 CharUnits ConstantAggregateBuilderBase::getOffsetFromGlobalTo(
size_t end)
const{
203 size_t cacheEnd = CachedOffsetEnd;
204 assert(cacheEnd <= end);
207 if (cacheEnd == end) {
208 return CachedOffsetFromGlobal;
214 if (cacheEnd <
Begin) {
215 assert(cacheEnd == 0);
216 assert(
Parent &&
"Begin != 0 for root builder");
220 offset = CachedOffsetFromGlobal;
224 if (cacheEnd != end) {
225 auto &layout = Builder.CGM.getDataLayout();
227 llvm::Constant *element = Builder.Buffer[cacheEnd];
228 assert(element !=
nullptr &&
229 "cannot compute offset when a placeholder is present");
233 layout.getABITypeAlignment(elementType)));
235 }
while (++cacheEnd != end);
239 CachedOffsetEnd = cacheEnd;
240 CachedOffsetFromGlobal = offset;
247 auto &buffer = getBuffer();
248 assert((
Begin < buffer.size() ||
249 (
Begin == buffer.size() && eltTy))
250 &&
"didn't add any array elements without element type");
251 auto elts = llvm::makeArrayRef(buffer).slice(
Begin);
252 if (!eltTy) eltTy = elts[0]->getType();
253 auto type = llvm::ArrayType::get(eltTy, elts.size());
254 auto constant = llvm::ConstantArray::get(
type, elts);
255 buffer.erase(buffer.begin() +
Begin, buffer.end());
263 auto &buffer = getBuffer();
264 auto elts = llvm::makeArrayRef(buffer).slice(
Begin);
266 if (ty ==
nullptr && elts.empty())
267 ty = llvm::StructType::get(Builder.CGM.getLLVMContext(), {}, Packed);
269 llvm::Constant *constant;
271 assert(ty->isPacked() == Packed);
272 constant = llvm::ConstantStruct::get(ty, elts);
274 constant = llvm::ConstantStruct::getAnon(elts, Packed);
277 buffer.erase(buffer.begin() +
Begin, buffer.end());
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
CharUnits alignTo(const CharUnits &Align) const
alignTo - Returns the next integer (mod 2**64) that is greater than or equal to this quantity and is ...
void addSize(CharUnits size)
Add an integer value of type size_t.
CharUnits - This is an opaque type for sizes expressed in character units.
llvm::Align getAsAlign() const
getAsAlign - Returns Quantity as a valid llvm::Align, Beware llvm::Align assumes power of two 8-bit b...
llvm::Constant * getAddrOfCurrentPosition(llvm::Type *type)
Produce an address which will eventually point to the next position to be filled. ...
llvm::Constant * finishArray(llvm::Type *eltTy)
void abandon()
Abandon this initializer.
llvm::Type * getType() const
Return the type of the initializer.
static CharUnits fromQuantity(QuantityType Quantity)
fromQuantity - Construct a CharUnits quantity from a raw integer type.
The l-value was considered opaque, so the alignment was determined from a type.
A "future" for a completed constant initializer, which can be passed around independently of any sub-...
Dataflow Directional Tag Classes.
llvm::Constant * finishStruct(llvm::StructType *structTy)
PlaceholderPosition addPlaceholderWithSize(llvm::Type *expectedType)
Add a placeholder, giving the expected type that will be filled in.
An opaque class to hold the abstract position of a placeholder.
void installInGlobal(llvm::GlobalVariable *global)
Install the initializer into a global variable.