void setParent(Module *parent);
- bool isConstantGlobal : 1; // Is this a global constant?
- unsigned threadLocalMode : 3; // Is this symbol "Thread Local",
- // if so, what is the desired model?
+ bool isConstantGlobal : 1; // Is this a global constant?
+ unsigned threadLocalMode : 3; // Is this symbol "Thread Local",
+ // if so, what is the desired
+ // model?
+ bool isExternallyInitializedConstant : 1; // Is this a global whose value
+ // can change from its initial
+ // value before global
+ // initializers are run?
public:
// allocate space for exactly one operand
/// automatically inserted into the end of the specified modules global list.
GlobalVariable(Type *Ty, bool isConstant, LinkageTypes Linkage,
Constant *Initializer = 0, const Twine &Name = "",
- ThreadLocalMode = NotThreadLocal, unsigned AddressSpace = 0);
+ ThreadLocalMode = NotThreadLocal, unsigned AddressSpace = 0,
+ bool isExternallyInitialized = false);
/// GlobalVariable ctor - This creates a global and inserts it before the
/// specified other global.
GlobalVariable(Module &M, Type *Ty, bool isConstant,
LinkageTypes Linkage, Constant *Initializer,
- const Twine &Name = "",
- GlobalVariable *InsertBefore = 0,
- ThreadLocalMode = NotThreadLocal,
- unsigned AddressSpace = 0);
+ const Twine &Name = "", GlobalVariable *InsertBefore = 0,
+ ThreadLocalMode = NotThreadLocal, unsigned AddressSpace = 0,
+ bool isExternallyInitialized = false);
~GlobalVariable() {
NumOperands = 1; // FIXME: needed by operator delete
return hasInitializer() &&
// The initializer of a global variable with weak linkage may change at
// link time.
- !mayBeOverridden();
+ !mayBeOverridden() &&
+ // The initializer of a global variable with the externally_initialized
+ // marker may change at runtime before C++ initializers are evaluated.
+ !isExternallyInitialized();
}
/// hasUniqueInitializer - Whether the global variable has an initializer, and
// instead. It is wrong to modify the initializer of a global variable
// with *_odr linkage because then different instances of the global may
// have different initializers, breaking the One Definition Rule.
- !isWeakForLinker();
+ !isWeakForLinker() &&
+ // It is not safe to modify initializers of global variables with the
+ // external_initializer marker since the value may be changed at runtime
+ // before C++ initializers are evaluated.
+ !isExternallyInitialized();
}
/// getInitializer - Return the initializer for this global variable. It is
return static_cast<ThreadLocalMode>(threadLocalMode);
}
+ bool isExternallyInitialized() const {
+ return isExternallyInitializedConstant;
+ }
+ void setExternallyInitialized(bool Val) {
+ isExternallyInitializedConstant = Val;
+ }
+
/// copyAttributesFrom - copy all additional attributes (those not needed to
/// create a GlobalVariable) from the GlobalVariable Src to this one.
void copyAttributesFrom(const GlobalValue *Src);