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();
129 ConstantAggregateBuilderBase::getRelativeOffset(llvm::IntegerType *offsetType,
130 llvm::Constant *target) {
131 return getRelativeOffsetToPosition(offsetType, target,
135 llvm::Constant *ConstantAggregateBuilderBase::getRelativeOffsetToPosition(
136 llvm::IntegerType *offsetType, llvm::Constant *target,
size_t position) {
142 target = llvm::ConstantExpr::getPtrToInt(target,
Builder.CGM.
IntPtrTy);
143 llvm::Constant *offset = llvm::ConstantExpr::getSub(target, base);
147 offset = llvm::ConstantExpr::getTrunc(offset, offsetType);
159 llvm::GlobalVariable::PrivateLinkage,
161 Builder.SelfReferences.emplace_back(dummy);
162 auto &entry =
Builder.SelfReferences.back();
163 (void)getGEPIndicesTo(entry.Indices, position +
Begin);
173 llvm::GlobalVariable::PrivateLinkage,
175 Builder.SelfReferences.emplace_back(dummy);
176 auto &entry =
Builder.SelfReferences.back();
181 void ConstantAggregateBuilderBase::getGEPIndicesTo(
183 size_t position)
const {
190 assert(indices.empty());
191 indices.push_back(llvm::ConstantInt::get(
Builder.CGM.
Int32Ty, 0));
194 assert(position >=
Begin);
213 layout.getABITypeAlignment(
type)));
222 CharUnits ConstantAggregateBuilderBase::getOffsetFromGlobalTo(
size_t end)
const{
224 assert(cacheEnd <= end);
227 if (cacheEnd == end) {
234 if (cacheEnd <
Begin) {
235 assert(cacheEnd == 0);
236 assert(
Parent &&
"Begin != 0 for root builder");
244 if (cacheEnd != end) {
247 llvm::Constant *element =
Builder.Buffer[cacheEnd];
248 assert(element !=
nullptr &&
249 "cannot compute offset when a placeholder is present");
250 llvm::Type *elementType = element->getType();
253 layout.getABITypeAlignment(elementType)));
255 }
while (++cacheEnd != end);
268 assert((
Begin < buffer.size() ||
269 (
Begin == buffer.size() && eltTy))
270 &&
"didn't add any array elements without element type");
271 auto elts = llvm::makeArrayRef(buffer).slice(
Begin);
272 if (!eltTy) eltTy = elts[0]->getType();
273 auto type = llvm::ArrayType::get(eltTy, elts.size());
274 auto constant = llvm::ConstantArray::get(
type, elts);
275 buffer.erase(buffer.begin() +
Begin, buffer.end());
284 auto elts = llvm::makeArrayRef(buffer).slice(
Begin);
286 if (ty ==
nullptr && elts.empty())
289 llvm::Constant *constant;
291 assert(ty->isPacked() ==
Packed);
292 constant = llvm::ConstantStruct::get(ty, elts);
294 constant = llvm::ConstantStruct::getAnon(elts,
Packed);
297 buffer.erase(buffer.begin() +
Begin, buffer.end());