mirror of
https://github.com/llvm/llvm-project.git
synced 2025-04-27 14:46:10 +00:00
[IR] Add method to GlobalVariable to change type of initializer. (#102553)
With opaque pointers, nothing directly uses the value type, so we can mutate it if we want. This avoid doing a complicated RAUW dance.
This commit is contained in:
parent
5c016bf40e
commit
2f8f58dd17
@ -370,38 +370,12 @@ CodeGenFunction::AddInitializerToStaticVarDecl(const VarDecl &D,
|
||||
assert(VarSize == CstSize && "Emitted constant has unexpected size");
|
||||
#endif
|
||||
|
||||
// The initializer may differ in type from the global. Rewrite
|
||||
// the global to match the initializer. (We have to do this
|
||||
// because some types, like unions, can't be completely represented
|
||||
// in the LLVM type system.)
|
||||
if (GV->getValueType() != Init->getType()) {
|
||||
llvm::GlobalVariable *OldGV = GV;
|
||||
|
||||
GV = new llvm::GlobalVariable(
|
||||
CGM.getModule(), Init->getType(), OldGV->isConstant(),
|
||||
OldGV->getLinkage(), Init, "",
|
||||
/*InsertBefore*/ OldGV, OldGV->getThreadLocalMode(),
|
||||
OldGV->getType()->getPointerAddressSpace());
|
||||
GV->setVisibility(OldGV->getVisibility());
|
||||
GV->setDSOLocal(OldGV->isDSOLocal());
|
||||
GV->setComdat(OldGV->getComdat());
|
||||
|
||||
// Steal the name of the old global
|
||||
GV->takeName(OldGV);
|
||||
|
||||
// Replace all uses of the old global with the new global
|
||||
OldGV->replaceAllUsesWith(GV);
|
||||
|
||||
// Erase the old global, since it is no longer used.
|
||||
OldGV->eraseFromParent();
|
||||
}
|
||||
|
||||
bool NeedsDtor =
|
||||
D.needsDestruction(getContext()) == QualType::DK_cxx_destructor;
|
||||
|
||||
GV->setConstant(
|
||||
D.getType().isConstantStorage(getContext(), true, !NeedsDtor));
|
||||
GV->setInitializer(Init);
|
||||
GV->replaceInitializer(Init);
|
||||
|
||||
emitter.finalize(GV);
|
||||
|
||||
|
@ -147,10 +147,16 @@ public:
|
||||
return static_cast<Constant*>(Op<0>().get());
|
||||
}
|
||||
/// setInitializer - Sets the initializer for this global variable, removing
|
||||
/// any existing initializer if InitVal==NULL. If this GV has type T*, the
|
||||
/// initializer must have type T.
|
||||
/// any existing initializer if InitVal==NULL. The initializer must have the
|
||||
/// type getValueType().
|
||||
void setInitializer(Constant *InitVal);
|
||||
|
||||
/// replaceInitializer - Sets the initializer for this global variable, and
|
||||
/// sets the value type of the global to the type of the initializer. The
|
||||
/// initializer must not be null. This may affect the global's alignment if
|
||||
/// it isn't explicitly set.
|
||||
void replaceInitializer(Constant *InitVal);
|
||||
|
||||
/// If the value is a global constant, its value is immutable throughout the
|
||||
/// runtime execution of the program. Assigning a value into the constant
|
||||
/// leads to undefined behavior.
|
||||
|
@ -503,6 +503,12 @@ void GlobalVariable::setInitializer(Constant *InitVal) {
|
||||
}
|
||||
}
|
||||
|
||||
void GlobalVariable::replaceInitializer(Constant *InitVal) {
|
||||
assert(InitVal && "Can't compute type of null initializer");
|
||||
ValueType = InitVal->getType();
|
||||
setInitializer(InitVal);
|
||||
}
|
||||
|
||||
/// Copy all additional attributes (those not needed to create a GlobalVariable)
|
||||
/// from the GlobalVariable Src to this one.
|
||||
void GlobalVariable::copyAttributesFrom(const GlobalVariable *Src) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user