forked from OSchip/llvm-project
parent
4afe0425db
commit
1d0ac7c5b8
|
@ -337,7 +337,8 @@ public:
|
|||
/// the specified element.
|
||||
Constant *getStructElement(unsigned Elt) const;
|
||||
|
||||
/// Return a zero of the right value for the specified GEP index.
|
||||
/// Return a zero of the right value for the specified GEP index if we can,
|
||||
/// otherwise return null (e.g. if C is a ConstantExpr).
|
||||
Constant *getElementValue(Constant *C) const;
|
||||
|
||||
/// Return a zero of the right value for the specified GEP index.
|
||||
|
@ -1219,7 +1220,8 @@ public:
|
|||
/// for the specified element.
|
||||
UndefValue *getStructElement(unsigned Elt) const;
|
||||
|
||||
/// Return an undef of the right value for the specified GEP index.
|
||||
/// Return an undef of the right value for the specified GEP index if we can,
|
||||
/// otherwise return null (e.g. if C is a ConstantExpr).
|
||||
UndefValue *getElementValue(Constant *C) const;
|
||||
|
||||
/// Return an undef of the right value for the specified GEP index.
|
||||
|
|
|
@ -191,7 +191,7 @@ bool Constant::isNotMinSignedValue() const {
|
|||
return false;
|
||||
}
|
||||
|
||||
// Constructor to create a '0' constant of arbitrary type...
|
||||
/// Constructor to create a '0' constant of arbitrary type.
|
||||
Constant *Constant::getNullValue(Type *Ty) {
|
||||
switch (Ty->getTypeID()) {
|
||||
case Type::IntegerTyID:
|
||||
|
@ -262,10 +262,6 @@ Constant *Constant::getAllOnesValue(Type *Ty) {
|
|||
getAllOnesValue(VTy->getElementType()));
|
||||
}
|
||||
|
||||
/// getAggregateElement - For aggregates (struct/array/vector) return the
|
||||
/// constant that corresponds to the specified element if possible, or null if
|
||||
/// not. This can return null if the element index is a ConstantExpr, or if
|
||||
/// 'this' is a constant expr.
|
||||
Constant *Constant::getAggregateElement(unsigned Elt) const {
|
||||
if (const ConstantAggregate *CC = dyn_cast<ConstantAggregate>(this))
|
||||
return Elt < CC->getNumOperands() ? CC->getOperand(Elt) : nullptr;
|
||||
|
@ -362,8 +358,6 @@ static bool canTrapImpl(const Constant *C,
|
|||
}
|
||||
}
|
||||
|
||||
/// canTrap - Return true if evaluation of this constant could trap. This is
|
||||
/// true for things like constant expressions that could divide by zero.
|
||||
bool Constant::canTrap() const {
|
||||
SmallPtrSet<const ConstantExpr *, 4> NonTrappingOps;
|
||||
return canTrapImpl(this, NonTrappingOps);
|
||||
|
@ -394,7 +388,6 @@ ConstHasGlobalValuePredicate(const Constant *C,
|
|||
return false;
|
||||
}
|
||||
|
||||
/// Return true if the value can vary between threads.
|
||||
bool Constant::isThreadDependent() const {
|
||||
auto DLLImportPredicate = [](const GlobalValue *GV) {
|
||||
return GV->isThreadLocal();
|
||||
|
@ -409,8 +402,6 @@ bool Constant::isDLLImportDependent() const {
|
|||
return ConstHasGlobalValuePredicate(this, DLLImportPredicate);
|
||||
}
|
||||
|
||||
/// Return true if the constant has users other than constant exprs and other
|
||||
/// dangling things.
|
||||
bool Constant::isConstantUsed() const {
|
||||
for (const User *U : users()) {
|
||||
const Constant *UC = dyn_cast<Constant>(U);
|
||||
|
@ -454,9 +445,8 @@ bool Constant::needsRelocation() const {
|
|||
return Result;
|
||||
}
|
||||
|
||||
/// removeDeadUsersOfConstant - If the specified constantexpr is dead, remove
|
||||
/// it. This involves recursively eliminating any dead users of the
|
||||
/// constantexpr.
|
||||
/// If the specified constantexpr is dead, remove it. This involves recursively
|
||||
/// eliminating any dead users of the constantexpr.
|
||||
static bool removeDeadUsersOfConstant(const Constant *C) {
|
||||
if (isa<GlobalValue>(C)) return false; // Cannot remove this
|
||||
|
||||
|
@ -472,10 +462,6 @@ static bool removeDeadUsersOfConstant(const Constant *C) {
|
|||
}
|
||||
|
||||
|
||||
/// removeDeadConstantUsers - If there are any dead constant users dangling
|
||||
/// off of this constant, remove them. This method is useful for clients
|
||||
/// that want to check to see if a global is unused, but don't want to deal
|
||||
/// with potentially dead constants hanging off of the globals.
|
||||
void Constant::removeDeadConstantUsers() const {
|
||||
Value::const_user_iterator I = user_begin(), E = user_end();
|
||||
Value::const_user_iterator LastNonDeadUser = E;
|
||||
|
@ -638,9 +624,6 @@ static const fltSemantics *TypeToFloatSemantics(Type *Ty) {
|
|||
|
||||
void ConstantFP::anchor() { }
|
||||
|
||||
/// get() - This returns a constant fp for the specified value in the
|
||||
/// specified type. This should only be used for simple constant values like
|
||||
/// 2.0/1.0 etc, that are known-valid both as double and as the target format.
|
||||
Constant *ConstantFP::get(Type *Ty, double V) {
|
||||
LLVMContext &Context = Ty->getContext();
|
||||
|
||||
|
@ -760,28 +743,20 @@ void ConstantFP::destroyConstantImpl() {
|
|||
// ConstantAggregateZero Implementation
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
/// getSequentialElement - If this CAZ has array or vector type, return a zero
|
||||
/// with the right element type.
|
||||
Constant *ConstantAggregateZero::getSequentialElement() const {
|
||||
return Constant::getNullValue(getType()->getSequentialElementType());
|
||||
}
|
||||
|
||||
/// getStructElement - If this CAZ has struct type, return a zero with the
|
||||
/// right element type for the specified element.
|
||||
Constant *ConstantAggregateZero::getStructElement(unsigned Elt) const {
|
||||
return Constant::getNullValue(getType()->getStructElementType(Elt));
|
||||
}
|
||||
|
||||
/// getElementValue - Return a zero of the right value for the specified GEP
|
||||
/// index if we can, otherwise return null (e.g. if C is a ConstantExpr).
|
||||
Constant *ConstantAggregateZero::getElementValue(Constant *C) const {
|
||||
if (isa<SequentialType>(getType()))
|
||||
return getSequentialElement();
|
||||
return getStructElement(cast<ConstantInt>(C)->getZExtValue());
|
||||
}
|
||||
|
||||
/// getElementValue - Return a zero of the right value for the specified GEP
|
||||
/// index.
|
||||
Constant *ConstantAggregateZero::getElementValue(unsigned Idx) const {
|
||||
if (isa<SequentialType>(getType()))
|
||||
return getSequentialElement();
|
||||
|
@ -801,28 +776,20 @@ unsigned ConstantAggregateZero::getNumElements() const {
|
|||
// UndefValue Implementation
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
/// getSequentialElement - If this undef has array or vector type, return an
|
||||
/// undef with the right element type.
|
||||
UndefValue *UndefValue::getSequentialElement() const {
|
||||
return UndefValue::get(getType()->getSequentialElementType());
|
||||
}
|
||||
|
||||
/// getStructElement - If this undef has struct type, return a zero with the
|
||||
/// right element type for the specified element.
|
||||
UndefValue *UndefValue::getStructElement(unsigned Elt) const {
|
||||
return UndefValue::get(getType()->getStructElementType(Elt));
|
||||
}
|
||||
|
||||
/// getElementValue - Return an undef of the right value for the specified GEP
|
||||
/// index if we can, otherwise return null (e.g. if C is a ConstantExpr).
|
||||
UndefValue *UndefValue::getElementValue(Constant *C) const {
|
||||
if (isa<SequentialType>(getType()))
|
||||
return getSequentialElement();
|
||||
return getStructElement(cast<ConstantInt>(C)->getZExtValue());
|
||||
}
|
||||
|
||||
/// getElementValue - Return an undef of the right value for the specified GEP
|
||||
/// index.
|
||||
UndefValue *UndefValue::getElementValue(unsigned Idx) const {
|
||||
if (isa<SequentialType>(getType()))
|
||||
return getSequentialElement();
|
||||
|
@ -959,8 +926,6 @@ Constant *ConstantArray::getImpl(ArrayType *Ty, ArrayRef<Constant*> V) {
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
/// getTypeForElements - Return an anonymous struct type to use for a constant
|
||||
/// with the specified set of elements. The list must not be empty.
|
||||
StructType *ConstantStruct::getTypeForElements(LLVMContext &Context,
|
||||
ArrayRef<Constant*> V,
|
||||
bool Packed) {
|
||||
|
@ -1148,8 +1113,6 @@ unsigned ConstantExpr::getPredicate() const {
|
|||
return cast<CompareConstantExpr>(this)->predicate;
|
||||
}
|
||||
|
||||
/// getWithOperandReplaced - Return a constant expression identical to this
|
||||
/// one, but with the specified operand set to the specified value.
|
||||
Constant *
|
||||
ConstantExpr::getWithOperandReplaced(unsigned OpNo, Constant *Op) const {
|
||||
assert(Op->getType() == getOperand(OpNo)->getType() &&
|
||||
|
@ -1164,9 +1127,6 @@ ConstantExpr::getWithOperandReplaced(unsigned OpNo, Constant *Op) const {
|
|||
return getWithOperands(NewOps);
|
||||
}
|
||||
|
||||
/// getWithOperands - This returns the current constant expression with the
|
||||
/// operands replaced with the specified values. The specified array must
|
||||
/// have the same number of operands as our current one.
|
||||
Constant *ConstantExpr::getWithOperands(ArrayRef<Constant *> Ops, Type *Ty,
|
||||
bool OnlyIfReduced, Type *SrcTy) const {
|
||||
assert(Ops.size() == getNumOperands() && "Operand count mismatch!");
|
||||
|
@ -1311,14 +1271,12 @@ ConstantAggregateZero *ConstantAggregateZero::get(Type *Ty) {
|
|||
return Entry;
|
||||
}
|
||||
|
||||
/// destroyConstant - Remove the constant from the constant table.
|
||||
///
|
||||
/// Remove the constant from the constant table.
|
||||
void ConstantAggregateZero::destroyConstantImpl() {
|
||||
getContext().pImpl->CAZConstants.erase(getType());
|
||||
}
|
||||
|
||||
/// destroyConstant - Remove the constant from the constant table...
|
||||
///
|
||||
/// Remove the constant from the constant table.
|
||||
void ConstantArray::destroyConstantImpl() {
|
||||
getType()->getContext().pImpl->ArrayConstants.remove(this);
|
||||
}
|
||||
|
@ -1327,20 +1285,16 @@ void ConstantArray::destroyConstantImpl() {
|
|||
//---- ConstantStruct::get() implementation...
|
||||
//
|
||||
|
||||
// destroyConstant - Remove the constant from the constant table...
|
||||
//
|
||||
/// Remove the constant from the constant table.
|
||||
void ConstantStruct::destroyConstantImpl() {
|
||||
getType()->getContext().pImpl->StructConstants.remove(this);
|
||||
}
|
||||
|
||||
// destroyConstant - Remove the constant from the constant table...
|
||||
//
|
||||
/// Remove the constant from the constant table.
|
||||
void ConstantVector::destroyConstantImpl() {
|
||||
getType()->getContext().pImpl->VectorConstants.remove(this);
|
||||
}
|
||||
|
||||
/// getSplatValue - If this is a splat vector constant, meaning that all of
|
||||
/// the elements have the same value, return that value. Otherwise return 0.
|
||||
Constant *Constant::getSplatValue() const {
|
||||
assert(this->getType()->isVectorTy() && "Only valid for vectors!");
|
||||
if (isa<ConstantAggregateZero>(this))
|
||||
|
@ -1352,8 +1306,6 @@ Constant *Constant::getSplatValue() const {
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
/// getSplatValue - If this is a splat constant, where all of the
|
||||
/// elements have the same value, return that value. Otherwise return null.
|
||||
Constant *ConstantVector::getSplatValue() const {
|
||||
// Check out first element.
|
||||
Constant *Elt = getOperand(0);
|
||||
|
@ -1364,8 +1316,6 @@ Constant *ConstantVector::getSplatValue() const {
|
|||
return Elt;
|
||||
}
|
||||
|
||||
/// If C is a constant integer then return its value, otherwise C must be a
|
||||
/// vector of constant integers, all equal, and the common value is returned.
|
||||
const APInt &Constant::getUniqueInteger() const {
|
||||
if (const ConstantInt *CI = dyn_cast<ConstantInt>(this))
|
||||
return CI->getValue();
|
||||
|
@ -1386,16 +1336,11 @@ ConstantPointerNull *ConstantPointerNull::get(PointerType *Ty) {
|
|||
return Entry;
|
||||
}
|
||||
|
||||
// destroyConstant - Remove the constant from the constant table...
|
||||
//
|
||||
/// Remove the constant from the constant table.
|
||||
void ConstantPointerNull::destroyConstantImpl() {
|
||||
getContext().pImpl->CPNConstants.erase(getType());
|
||||
}
|
||||
|
||||
|
||||
//---- UndefValue::get() implementation.
|
||||
//
|
||||
|
||||
UndefValue *UndefValue::get(Type *Ty) {
|
||||
UndefValue *&Entry = Ty->getContext().pImpl->UVConstants[Ty];
|
||||
if (!Entry)
|
||||
|
@ -1404,16 +1349,12 @@ UndefValue *UndefValue::get(Type *Ty) {
|
|||
return Entry;
|
||||
}
|
||||
|
||||
// destroyConstant - Remove the constant from the constant table.
|
||||
//
|
||||
/// Remove the constant from the constant table.
|
||||
void UndefValue::destroyConstantImpl() {
|
||||
// Free the constant and any dangling references to it.
|
||||
getContext().pImpl->UVConstants.erase(getType());
|
||||
}
|
||||
|
||||
//---- BlockAddress::get() implementation.
|
||||
//
|
||||
|
||||
BlockAddress *BlockAddress::get(BasicBlock *BB) {
|
||||
assert(BB->getParent() && "Block must have a parent");
|
||||
return get(BB->getParent(), BB);
|
||||
|
@ -1449,8 +1390,7 @@ BlockAddress *BlockAddress::lookup(const BasicBlock *BB) {
|
|||
return BA;
|
||||
}
|
||||
|
||||
// destroyConstant - Remove the constant from the constant table.
|
||||
//
|
||||
/// Remove the constant from the constant table.
|
||||
void BlockAddress::destroyConstantImpl() {
|
||||
getFunction()->getType()->getContext().pImpl
|
||||
->BlockAddresses.erase(std::make_pair(getFunction(), getBasicBlock()));
|
||||
|
@ -2271,9 +2211,6 @@ Constant *ConstantExpr::getAShr(Constant *C1, Constant *C2, bool isExact) {
|
|||
isExact ? PossiblyExactOperator::IsExact : 0);
|
||||
}
|
||||
|
||||
/// getBinOpIdentity - Return the identity for the given binary operation,
|
||||
/// i.e. a constant C such that X op C = X and C op X = X for every X. It
|
||||
/// returns null if the operator doesn't have an identity.
|
||||
Constant *ConstantExpr::getBinOpIdentity(unsigned Opcode, Type *Ty) {
|
||||
switch (Opcode) {
|
||||
default:
|
||||
|
@ -2293,10 +2230,6 @@ Constant *ConstantExpr::getBinOpIdentity(unsigned Opcode, Type *Ty) {
|
|||
}
|
||||
}
|
||||
|
||||
/// getBinOpAbsorber - Return the absorbing element for the given binary
|
||||
/// operation, i.e. a constant C such that X op C = C and C op X = C for
|
||||
/// every X. For example, this returns zero for integer multiplication.
|
||||
/// It returns null if the operator doesn't have an absorbing element.
|
||||
Constant *ConstantExpr::getBinOpAbsorber(unsigned Opcode, Type *Ty) {
|
||||
switch (Opcode) {
|
||||
default:
|
||||
|
@ -2312,8 +2245,7 @@ Constant *ConstantExpr::getBinOpAbsorber(unsigned Opcode, Type *Ty) {
|
|||
}
|
||||
}
|
||||
|
||||
// destroyConstant - Remove the constant from the constant table...
|
||||
//
|
||||
/// Remove the constant from the constant table.
|
||||
void ConstantExpr::destroyConstantImpl() {
|
||||
getType()->getContext().pImpl->ExprConstants.remove(this);
|
||||
}
|
||||
|
@ -2350,7 +2282,6 @@ Type *GetElementPtrConstantExpr::getResultElementType() const {
|
|||
void ConstantDataArray::anchor() {}
|
||||
void ConstantDataVector::anchor() {}
|
||||
|
||||
/// getElementType - Return the element type of the array/vector.
|
||||
Type *ConstantDataSequential::getElementType() const {
|
||||
return getType()->getElementType();
|
||||
}
|
||||
|
@ -2359,10 +2290,6 @@ StringRef ConstantDataSequential::getRawDataValues() const {
|
|||
return StringRef(DataElements, getNumElements()*getElementByteSize());
|
||||
}
|
||||
|
||||
/// isElementTypeCompatible - Return true if a ConstantDataSequential can be
|
||||
/// formed with a vector or array of the specified element type.
|
||||
/// ConstantDataArray only works with normal float and int types that are
|
||||
/// stored densely in memory, not with things like i42 or x86_f80.
|
||||
bool ConstantDataSequential::isElementTypeCompatible(Type *Ty) {
|
||||
if (Ty->isHalfTy() || Ty->isFloatTy() || Ty->isDoubleTy()) return true;
|
||||
if (auto *IT = dyn_cast<IntegerType>(Ty)) {
|
||||
|
@ -2378,7 +2305,6 @@ bool ConstantDataSequential::isElementTypeCompatible(Type *Ty) {
|
|||
return false;
|
||||
}
|
||||
|
||||
/// getNumElements - Return the number of elements in the array or vector.
|
||||
unsigned ConstantDataSequential::getNumElements() const {
|
||||
if (ArrayType *AT = dyn_cast<ArrayType>(getType()))
|
||||
return AT->getNumElements();
|
||||
|
@ -2386,19 +2312,18 @@ unsigned ConstantDataSequential::getNumElements() const {
|
|||
}
|
||||
|
||||
|
||||
/// getElementByteSize - Return the size in bytes of the elements in the data.
|
||||
uint64_t ConstantDataSequential::getElementByteSize() const {
|
||||
return getElementType()->getPrimitiveSizeInBits()/8;
|
||||
}
|
||||
|
||||
/// getElementPointer - Return the start of the specified element.
|
||||
/// Return the start of the specified element.
|
||||
const char *ConstantDataSequential::getElementPointer(unsigned Elt) const {
|
||||
assert(Elt < getNumElements() && "Invalid Elt");
|
||||
return DataElements+Elt*getElementByteSize();
|
||||
}
|
||||
|
||||
|
||||
/// isAllZeros - return true if the array is empty or all zeros.
|
||||
/// Return true if the array is empty or all zeros.
|
||||
static bool isAllZeros(StringRef Arr) {
|
||||
for (StringRef::iterator I = Arr.begin(), E = Arr.end(); I != E; ++I)
|
||||
if (*I != 0)
|
||||
|
@ -2406,7 +2331,7 @@ static bool isAllZeros(StringRef Arr) {
|
|||
return true;
|
||||
}
|
||||
|
||||
/// getImpl - This is the underlying implementation of all of the
|
||||
/// This is the underlying implementation of all of the
|
||||
/// ConstantDataSequential::get methods. They all thunk down to here, providing
|
||||
/// the correct element type. We take the bytes in as a StringRef because
|
||||
/// we *want* an underlying "char*" to avoid TBAA type punning violations.
|
||||
|
@ -2537,11 +2462,6 @@ Constant *ConstantDataArray::getFP(LLVMContext &Context,
|
|||
return getImpl(StringRef(const_cast<char *>(Data), Elts.size() * 8), Ty);
|
||||
}
|
||||
|
||||
/// getString - This method constructs a CDS and initializes it with a text
|
||||
/// string. The default behavior (AddNull==true) causes a null terminator to
|
||||
/// be placed at the end of the array (increasing the length of the string by
|
||||
/// one more than the StringRef would normally indicate. Pass AddNull=false
|
||||
/// to disable this behavior.
|
||||
Constant *ConstantDataArray::getString(LLVMContext &Context,
|
||||
StringRef Str, bool AddNull) {
|
||||
if (!AddNull) {
|
||||
|
@ -2656,8 +2576,6 @@ Constant *ConstantDataVector::getSplat(unsigned NumElts, Constant *V) {
|
|||
}
|
||||
|
||||
|
||||
/// getElementAsInteger - If this is a sequential container of integers (of
|
||||
/// any size), return the specified element in the low bits of a uint64_t.
|
||||
uint64_t ConstantDataSequential::getElementAsInteger(unsigned Elt) const {
|
||||
assert(isa<IntegerType>(getElementType()) &&
|
||||
"Accessor can only be used when element is an integer");
|
||||
|
@ -2678,8 +2596,6 @@ uint64_t ConstantDataSequential::getElementAsInteger(unsigned Elt) const {
|
|||
}
|
||||
}
|
||||
|
||||
/// getElementAsAPFloat - If this is a sequential container of floating point
|
||||
/// type, return the specified element as an APFloat.
|
||||
APFloat ConstantDataSequential::getElementAsAPFloat(unsigned Elt) const {
|
||||
const char *EltPtr = getElementPointer(Elt);
|
||||
|
||||
|
@ -2701,8 +2617,6 @@ APFloat ConstantDataSequential::getElementAsAPFloat(unsigned Elt) const {
|
|||
}
|
||||
}
|
||||
|
||||
/// getElementAsFloat - If this is an sequential container of floats, return
|
||||
/// the specified element as a float.
|
||||
float ConstantDataSequential::getElementAsFloat(unsigned Elt) const {
|
||||
assert(getElementType()->isFloatTy() &&
|
||||
"Accessor can only be used when element is a 'float'");
|
||||
|
@ -2710,8 +2624,6 @@ float ConstantDataSequential::getElementAsFloat(unsigned Elt) const {
|
|||
return *const_cast<float *>(EltPtr);
|
||||
}
|
||||
|
||||
/// getElementAsDouble - If this is an sequential container of doubles, return
|
||||
/// the specified element as a float.
|
||||
double ConstantDataSequential::getElementAsDouble(unsigned Elt) const {
|
||||
assert(getElementType()->isDoubleTy() &&
|
||||
"Accessor can only be used when element is a 'float'");
|
||||
|
@ -2720,9 +2632,6 @@ double ConstantDataSequential::getElementAsDouble(unsigned Elt) const {
|
|||
return *const_cast<double *>(EltPtr);
|
||||
}
|
||||
|
||||
/// getElementAsConstant - Return a Constant for a specified index's element.
|
||||
/// Note that this has to compute a new constant to return, so it isn't as
|
||||
/// efficient as getElementAsInteger/Float/Double.
|
||||
Constant *ConstantDataSequential::getElementAsConstant(unsigned Elt) const {
|
||||
if (getElementType()->isHalfTy() || getElementType()->isFloatTy() ||
|
||||
getElementType()->isDoubleTy())
|
||||
|
@ -2731,13 +2640,10 @@ Constant *ConstantDataSequential::getElementAsConstant(unsigned Elt) const {
|
|||
return ConstantInt::get(getElementType(), getElementAsInteger(Elt));
|
||||
}
|
||||
|
||||
/// isString - This method returns true if this is an array of i8.
|
||||
bool ConstantDataSequential::isString() const {
|
||||
return isa<ArrayType>(getType()) && getElementType()->isIntegerTy(8);
|
||||
}
|
||||
|
||||
/// isCString - This method returns true if the array "isString", ends with a
|
||||
/// nul byte, and does not contains any other nul bytes.
|
||||
bool ConstantDataSequential::isCString() const {
|
||||
if (!isString())
|
||||
return false;
|
||||
|
@ -2751,8 +2657,6 @@ bool ConstantDataSequential::isCString() const {
|
|||
return Str.drop_back().find(0) == StringRef::npos;
|
||||
}
|
||||
|
||||
/// getSplatValue - If this is a splat constant, meaning that all of the
|
||||
/// elements have the same value, return that value. Otherwise return nullptr.
|
||||
Constant *ConstantDataVector::getSplatValue() const {
|
||||
const char *Base = getRawDataValues().data();
|
||||
|
||||
|
|
Loading…
Reference in New Issue