19using 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();
52ConstantInitBuilderBase::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);
67ConstantInitBuilderBase::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);
87void ConstantInitBuilderBase::setGlobalInitializer(llvm::GlobalVariable *GV,
88 llvm::Constant *initializer){
89 GV->setInitializer(initializer);
91 if (!SelfReferences.empty())
92 resolveSelfReferences(GV);
95void 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();
107void 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::PoisonValue::get(dummy->getType()));
118 dummy->eraseFromParent();
120 SelfReferences.clear();
129ConstantAggregateBuilderBase::getRelativeOffset(llvm::IntegerType *offsetType,
130 llvm::Constant *target) {
131 return getRelativeOffsetToPosition(offsetType, target,
135llvm::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();
181void 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);
221CharUnits ConstantAggregateBuilderBase::getOffsetFromGlobalTo(
size_t end)
const{
223 assert(cacheEnd <= end);
226 if (cacheEnd == end) {
233 if (cacheEnd <
Begin) {
234 assert(cacheEnd == 0);
235 assert(
Parent &&
"Begin != 0 for root builder");
243 if (cacheEnd != end) {
246 llvm::Constant *element =
Builder.Buffer[cacheEnd];
247 assert(element !=
nullptr &&
248 "cannot compute offset when a placeholder is present");
249 llvm::Type *elementType = element->getType();
254 }
while (++cacheEnd != end);
267 assert((
Begin < buffer.size() ||
268 (
Begin == buffer.size() && eltTy))
269 &&
"didn't add any array elements without element type");
271 if (!eltTy) eltTy = elts[0]->getType();
272 auto type = llvm::ArrayType::get(eltTy, elts.size());
273 auto constant = llvm::ConstantArray::get(
type, elts);
274 buffer.erase(buffer.begin() +
Begin, buffer.end());
285 if (ty ==
nullptr && elts.empty())
288 llvm::Constant *constant;
290 assert(ty->isPacked() ==
Packed);
291 constant = llvm::ConstantStruct::get(ty, elts);
293 constant = llvm::ConstantStruct::getAnon(elts,
Packed);
296 buffer.erase(buffer.begin() +
Begin, buffer.end());
308 llvm::Constant *StorageAddress =
nullptr;
314 Pointer, Schema, StorageAddress, CalleeDecl, CalleeType);
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...
static CharUnits fromQuantity(QuantityType Quantity)
fromQuantity - Construct a CharUnits quantity from a raw integer type.
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 ...
llvm::Module & getModule() const
const llvm::DataLayout & getDataLayout() const
llvm::LLVMContext & getLLVMContext()
llvm::Constant * getConstantSignedPointer(llvm::Constant *Pointer, const PointerAuthSchema &Schema, llvm::Constant *StorageAddress, GlobalDecl SchemaDecl, QualType SchemaType)
Sign a constant pointer using the given scheme, producing a constant with the same IR type.
bool shouldSignPointer(const PointerAuthSchema &Schema)
Does a given PointerAuthScheme require us to sign a value.
llvm::ConstantInt * getSize(CharUnits numChars)
Emit the given number of characters as a value of type size_t.
An opaque class to hold the abstract position of a placeholder.
llvm::Constant * getAddrOfPosition(llvm::Type *type, size_t position)
Produce an address which points to a position in the aggregate being constructed.
CharUnits CachedOffsetFromGlobal
PlaceholderPosition addPlaceholder()
Add a placeholder value to the structure.
llvm::SmallVectorImpl< llvm::Constant * > & getBuffer()
void add(llvm::Constant *value)
Add a new value to this initializer.
llvm::Constant * finishArray(llvm::Type *eltTy)
PlaceholderPosition addPlaceholderWithSize(llvm::Type *expectedType)
Add a placeholder, giving the expected type that will be filled in.
void addSize(CharUnits size)
Add an integer value of type size_t.
llvm::Constant * finishStruct(llvm::StructType *structTy)
llvm::Constant * getAddrOfCurrentPosition(llvm::Type *type)
Produce an address which will eventually point to the next position to be filled.
CharUnits getNextOffsetFromGlobal() const
Return the offset from the start of the initializer to the next position, assuming no padding is requ...
llvm::ArrayRef< llvm::Constant * > getGEPIndicesToCurrentPosition(llvm::SmallVectorImpl< llvm::Constant * > &indices)
size_t size() const
Return the number of elements that have been added to this struct or array.
void addSignedPointer(llvm::Constant *Pointer, const PointerAuthSchema &Schema, GlobalDecl CalleeDecl, QualType CalleeType)
Add a signed pointer using the given pointer authentication schema.
ConstantInitBuilderBase & Builder
ConstantAggregateBuilderBase * Parent
A convenience builder class for complex constant initializers, especially for anonymous global struct...
friend class ConstantInitFuture
A "future" for a completed constant initializer, which can be passed around independently of any sub-...
llvm::Type * getType() const
Return the type of the initializer.
void abandon()
Abandon this initializer.
void installInGlobal(llvm::GlobalVariable *global)
Install the initializer into a global variable.
GlobalDecl - represents a global declaration.
bool isAddressDiscriminated() const
A (possibly-)qualified type.
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
The JSON file list parser is used to communicate input to InstallAPI.
llvm::IntegerType * Int32Ty
llvm::IntegerType * IntPtrTy