19 using namespace clang;
20 using namespace CodeGen;
23 assert(Data &&
"dereferencing null future");
24 if (Data.is<llvm::Constant*>()) {
25 return Data.get<llvm::Constant*>()->
getType();
32 assert(Data &&
"abandoning null future");
40 assert(Data &&
"installing null future");
41 if (Data.is<llvm::Constant*>()) {
42 GV->setInitializer(Data.get<llvm::Constant*>());
45 assert(builder.Buffer.size() == 1);
46 builder.setGlobalInitializer(GV, builder.Buffer[0]);
47 builder.Buffer.clear();
53 ConstantInitBuilderBase::createFuture(llvm::Constant *initializer) {
54 assert(Buffer.empty() &&
"buffer not current empty");
55 Buffer.push_back(initializer);
62 assert(!builder->Frozen);
63 assert(builder->Buffer.size() == 1);
64 assert(builder->Buffer[0] !=
nullptr);
67 llvm::GlobalVariable *
68 ConstantInitBuilderBase::createGlobal(llvm::Constant *initializer,
69 const llvm::Twine &name,
72 llvm::GlobalValue::LinkageTypes linkage,
73 unsigned addressSpace) {
74 auto GV =
new llvm::GlobalVariable(CGM.
getModule(),
75 initializer->getType(),
81 llvm::GlobalValue::NotThreadLocal,
84 resolveSelfReferences(GV);
88 void ConstantInitBuilderBase::setGlobalInitializer(llvm::GlobalVariable *GV,
89 llvm::Constant *initializer){
90 GV->setInitializer(initializer);
92 if (!SelfReferences.empty())
93 resolveSelfReferences(GV);
96 void ConstantInitBuilderBase::resolveSelfReferences(llvm::GlobalVariable *GV) {
97 for (
auto &entry : SelfReferences) {
98 llvm::Constant *resolvedReference =
99 llvm::ConstantExpr::getInBoundsGetElementPtr(
100 GV->getValueType(), GV, entry.Indices);
101 auto dummy = entry.Dummy;
102 dummy->replaceAllUsesWith(resolvedReference);
103 dummy->eraseFromParent();
105 SelfReferences.clear();
108 void ConstantInitBuilderBase::abandon(
size_t newEnd) {
110 Buffer.erase(Buffer.begin() + newEnd, Buffer.end());
116 for (
auto &entry : SelfReferences) {
117 auto dummy = entry.Dummy;
118 dummy->replaceAllUsesWith(llvm::UndefValue::get(dummy->getType()));
119 dummy->eraseFromParent();
121 SelfReferences.clear();
130 ConstantAggregateBuilderBase::getRelativeOffset(llvm::IntegerType *offsetType,
131 llvm::Constant *target) {
137 target = llvm::ConstantExpr::getPtrToInt(target,
Builder.CGM.
IntPtrTy);
138 llvm::Constant *offset = llvm::ConstantExpr::getSub(target, base);
142 offset = llvm::ConstantExpr::getTrunc(offset, offsetType);
154 llvm::GlobalVariable::PrivateLinkage,
156 Builder.SelfReferences.emplace_back(dummy);
157 auto &entry =
Builder.SelfReferences.back();
162 void ConstantAggregateBuilderBase::getGEPIndicesTo(
164 size_t position)
const {
171 assert(indices.empty());
172 indices.push_back(llvm::ConstantInt::get(
Builder.CGM.
Int32Ty, 0));
175 assert(position >=
Begin);
194 layout.getABITypeAlignment(type)));
203 CharUnits ConstantAggregateBuilderBase::getOffsetFromGlobalTo(
size_t end)
const{
205 assert(cacheEnd <= end);
208 if (cacheEnd == end) {
215 if (cacheEnd <
Begin) {
216 assert(cacheEnd == 0);
217 assert(
Parent &&
"Begin != 0 for root builder");
225 if (cacheEnd != end) {
228 llvm::Constant *element =
Builder.Buffer[cacheEnd];
229 assert(element !=
nullptr &&
230 "cannot compute offset when a placeholder is present");
234 layout.getABITypeAlignment(elementType)));
236 }
while (++cacheEnd != end);
249 assert((
Begin < buffer.size() ||
250 (
Begin == buffer.size() && eltTy))
251 &&
"didn't add any array elements without element type");
252 auto elts = llvm::makeArrayRef(buffer).slice(
Begin);
253 if (!eltTy) eltTy = elts[0]->getType();
254 auto type = llvm::ArrayType::get(eltTy, elts.size());
255 auto constant = llvm::ConstantArray::get(
type, elts);
256 buffer.erase(buffer.begin() +
Begin, buffer.end());
265 auto elts = llvm::makeArrayRef(buffer).slice(
Begin);
267 if (ty ==
nullptr && elts.empty())
270 llvm::Constant *constant;
272 assert(ty->isPacked() ==
Packed);
273 constant = llvm::ConstantStruct::get(ty, elts);
275 constant = llvm::ConstantStruct::getAnon(elts,
Packed);
278 buffer.erase(buffer.begin() +
Begin, buffer.end());
llvm::Module & getModule() const
llvm::LLVMContext & getLLVMContext()
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
const llvm::DataLayout & getDataLayout() const
void addSize(CharUnits size)
Add an integer value of type size_t.
std::unique_ptr< llvm::MemoryBuffer > Buffer
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 ...
PlaceholderPosition addPlaceholder()
Add a placeholder value to the structure.
CharUnits - This is an opaque type for sizes expressed in character units.
llvm::Type * getType() const
Return the type of the initializer.
llvm::Constant * getAddrOfCurrentPosition(llvm::Type *type)
Produce an address which will eventually point to the the next position to be filled.
llvm::Constant * finishArray(llvm::Type *eltTy)
void abandon()
Abandon this initializer.
static CharUnits fromQuantity(QuantityType Quantity)
fromQuantity - Construct a CharUnits quantity from a raw integer type.
llvm::IntegerType * Int32Ty
void add(llvm::Constant *value)
Add a new value to this initializer.
The l-value was considered opaque, so the alignment was determined from a type.
ConstantAggregateBuilderBase * Parent
CharUnits CachedOffsetFromGlobal
A "future" for a completed constant initializer, which can be passed around independently of any sub-...
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
CharUnits getNextOffsetFromGlobal() const
Return the offset from the start of the initializer to the next position, assuming no padding is requ...
llvm::IntegerType * IntPtrTy
friend class ConstantInitFuture
llvm::SmallVectorImpl< llvm::Constant * > & getBuffer()
llvm::Constant * finishStruct(llvm::StructType *structTy)
llvm::ArrayRef< llvm::Constant * > getGEPIndicesToCurrentPosition(llvm::SmallVectorImpl< llvm::Constant * > &indices)
llvm::ConstantInt * getSize(CharUnits numChars)
Emit the given number of characters as a value of type size_t.
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.
ConstantInitBuilderBase & Builder
void installInGlobal(llvm::GlobalVariable *global)
Install the initializer into a global variable.