mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-03 17:59:46 +02:00
GP-4095 Check for primitive data-type when triggering double precision
This commit is contained in:
parent
1b813ed33e
commit
60cf8311f1
8 changed files with 76 additions and 19 deletions
|
@ -1667,8 +1667,8 @@ int4 ActionParamDouble::apply(Funcdata &data)
|
||||||
for(int4 i=0;i<numparams;++i) {
|
for(int4 i=0;i<numparams;++i) {
|
||||||
ProtoParameter *param = fp.getParam(i);
|
ProtoParameter *param = fp.getParam(i);
|
||||||
Datatype *tp = param->getType();
|
Datatype *tp = param->getType();
|
||||||
type_metatype mt = tp->getMetatype();
|
if (!tp->isPrimitiveWhole())
|
||||||
if ((mt==TYPE_ARRAY)||(mt==TYPE_STRUCT)) continue; // Not double precision objects
|
continue; // Not double precision objects
|
||||||
Varnode *vn = data.findVarnodeInput(tp->getSize(),param->getAddress());
|
Varnode *vn = data.findVarnodeInput(tp->getSize(),param->getAddress());
|
||||||
if (vn == (Varnode *)0) continue;
|
if (vn == (Varnode *)0) continue;
|
||||||
if (vn->getSize() < minDoubleSize) continue;
|
if (vn->getSize() < minDoubleSize) continue;
|
||||||
|
|
|
@ -693,6 +693,14 @@ PcodeOp *SplitVarnode::findOutExist(void)
|
||||||
return findEarliestSplitPoint();
|
return findEarliestSplitPoint();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// If the logical whole is a constant and is too big to be represented internally return \b true.
|
||||||
|
/// \return \b true if \b this is a constant and too big
|
||||||
|
bool SplitVarnode::exceedsConstPrecision(void) const
|
||||||
|
|
||||||
|
{
|
||||||
|
return isConstant() && (wholesize > sizeof(uintb));
|
||||||
|
}
|
||||||
|
|
||||||
/// \brief Check if the values in the given Varnodes differ by the given size
|
/// \brief Check if the values in the given Varnodes differ by the given size
|
||||||
///
|
///
|
||||||
/// Return \b true, if the (possibly dynamic) value represented by the given \b vn1 plus \b size1
|
/// Return \b true, if the (possibly dynamic) value represented by the given \b vn1 plus \b size1
|
||||||
|
@ -1543,6 +1551,8 @@ bool AddForm::applyRule(SplitVarnode &i,PcodeOp *op,bool workishi,Funcdata &data
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
indoub.initPartial(in.getSize(),lo2,hi2);
|
indoub.initPartial(in.getSize(),lo2,hi2);
|
||||||
|
if (indoub.exceedsConstPrecision())
|
||||||
|
return false;
|
||||||
outdoub.initPartial(in.getSize(),reslo,reshi);
|
outdoub.initPartial(in.getSize(),reslo,reshi);
|
||||||
existop = SplitVarnode::prepareBinaryOp(outdoub,in,indoub);
|
existop = SplitVarnode::prepareBinaryOp(outdoub,in,indoub);
|
||||||
if (existop == (PcodeOp *)0)
|
if (existop == (PcodeOp *)0)
|
||||||
|
@ -1636,6 +1646,8 @@ bool SubForm::applyRule(SplitVarnode &i,PcodeOp *op,bool workishi,Funcdata &data
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
indoub.initPartial(in.getSize(),lo2,hi2);
|
indoub.initPartial(in.getSize(),lo2,hi2);
|
||||||
|
if (indoub.exceedsConstPrecision())
|
||||||
|
return false;
|
||||||
outdoub.initPartial(in.getSize(),reslo,reshi);
|
outdoub.initPartial(in.getSize(),reslo,reshi);
|
||||||
existop = SplitVarnode::prepareBinaryOp(outdoub,in,indoub);
|
existop = SplitVarnode::prepareBinaryOp(outdoub,in,indoub);
|
||||||
if (existop == (PcodeOp *)0)
|
if (existop == (PcodeOp *)0)
|
||||||
|
@ -1757,6 +1769,8 @@ bool LogicalForm::applyRule(SplitVarnode &i,PcodeOp *lop,bool workishi,Funcdata
|
||||||
|
|
||||||
outdoub.initPartial(in.getSize(),loop->getOut(),hiop->getOut());
|
outdoub.initPartial(in.getSize(),loop->getOut(),hiop->getOut());
|
||||||
indoub.initPartial(in.getSize(),lo2,hi2);
|
indoub.initPartial(in.getSize(),lo2,hi2);
|
||||||
|
if (indoub.exceedsConstPrecision())
|
||||||
|
return false;
|
||||||
existop = SplitVarnode::prepareBinaryOp(outdoub,in,indoub);
|
existop = SplitVarnode::prepareBinaryOp(outdoub,in,indoub);
|
||||||
if (existop == (PcodeOp *)0)
|
if (existop == (PcodeOp *)0)
|
||||||
return false;
|
return false;
|
||||||
|
@ -1817,6 +1831,8 @@ bool Equal1Form::applyRule(SplitVarnode &i,PcodeOp *hop,bool workishi,Funcdata &
|
||||||
++iter3;
|
++iter3;
|
||||||
|
|
||||||
in2.initPartial(in1.getSize(),lo2,hi2);
|
in2.initPartial(in1.getSize(),lo2,hi2);
|
||||||
|
if (in2.exceedsConstPrecision())
|
||||||
|
continue;
|
||||||
|
|
||||||
if ((hibool->code() == CPUI_CBRANCH)&&(lobool->code()==CPUI_CBRANCH)) {
|
if ((hibool->code() == CPUI_CBRANCH)&&(lobool->code()==CPUI_CBRANCH)) {
|
||||||
// Branching form of the equal operation
|
// Branching form of the equal operation
|
||||||
|
@ -1958,8 +1974,10 @@ bool Equal2Form::applyRule(SplitVarnode &i,PcodeOp *op,bool workishi,Funcdata &d
|
||||||
hixor = (PcodeOp *)0;
|
hixor = (PcodeOp *)0;
|
||||||
hi2 = (Varnode *)0;
|
hi2 = (Varnode *)0;
|
||||||
if (fillOutFromOr(data)) {
|
if (fillOutFromOr(data)) {
|
||||||
SplitVarnode::replaceBoolOp(data,equalop,in,param2,equalop->code());
|
if (!param2.exceedsConstPrecision()) {
|
||||||
return true;
|
SplitVarnode::replaceBoolOp(data,equalop,in,param2,equalop->code());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else { // We see an XOR
|
else { // We see an XOR
|
||||||
|
@ -1976,8 +1994,10 @@ bool Equal2Form::applyRule(SplitVarnode &i,PcodeOp *op,bool workishi,Funcdata &d
|
||||||
if (orop->code() != CPUI_INT_OR) continue;
|
if (orop->code() != CPUI_INT_OR) continue;
|
||||||
orhislot = orop->getSlot(vn);
|
orhislot = orop->getSlot(vn);
|
||||||
if (fillOutFromOr(data)) {
|
if (fillOutFromOr(data)) {
|
||||||
SplitVarnode::replaceBoolOp(data,equalop,in,param2,equalop->code());
|
if (!param2.exceedsConstPrecision()) {
|
||||||
return true;
|
SplitVarnode::replaceBoolOp(data,equalop,in,param2,equalop->code());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2020,6 +2040,8 @@ bool Equal3Form::applyRule(SplitVarnode &i,PcodeOp *op,bool workishi,Funcdata &d
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
SplitVarnode in2(in.getSize(),calc_mask(in.getSize())); // Create the -1 value
|
SplitVarnode in2(in.getSize(),calc_mask(in.getSize())); // Create the -1 value
|
||||||
|
if (in2.exceedsConstPrecision())
|
||||||
|
return false;
|
||||||
if (!SplitVarnode::prepareBoolOp(in,in2,compareop)) return false;
|
if (!SplitVarnode::prepareBoolOp(in,in2,compareop)) return false;
|
||||||
SplitVarnode::replaceBoolOp(data,compareop,in,in2,compareop->code());
|
SplitVarnode::replaceBoolOp(data,compareop,in,in2,compareop->code());
|
||||||
return true;
|
return true;
|
||||||
|
@ -2483,6 +2505,8 @@ bool LessThreeWay::applyRule(SplitVarnode &i,PcodeOp *loop,bool workishi,Funcdat
|
||||||
if (!mapFromLow(loop)) return false;
|
if (!mapFromLow(loop)) return false;
|
||||||
bool res = testReplace();
|
bool res = testReplace();
|
||||||
if (res) {
|
if (res) {
|
||||||
|
if (in2.exceedsConstPrecision())
|
||||||
|
return false;
|
||||||
if (hislot==0)
|
if (hislot==0)
|
||||||
SplitVarnode::createBoolOp(data,hilessbool,in,in2,finalopc);
|
SplitVarnode::createBoolOp(data,hilessbool,in,in2,finalopc);
|
||||||
else
|
else
|
||||||
|
@ -2527,6 +2551,8 @@ bool LessConstForm::applyRule(SplitVarnode &i,PcodeOp *op,bool workishi,Funcdata
|
||||||
if (desc->code() != CPUI_CBRANCH) return false;
|
if (desc->code() != CPUI_CBRANCH) return false;
|
||||||
|
|
||||||
constin.initPartial(in.getSize(),val);
|
constin.initPartial(in.getSize(),val);
|
||||||
|
if (constin.exceedsConstPrecision())
|
||||||
|
return false;
|
||||||
|
|
||||||
if (inslot==0) {
|
if (inslot==0) {
|
||||||
if (SplitVarnode::prepareBoolOp(in,constin,op)) {
|
if (SplitVarnode::prepareBoolOp(in,constin,op)) {
|
||||||
|
@ -2967,6 +2993,8 @@ bool MultForm::replace(Funcdata &data)
|
||||||
{ // We have matched a double precision multiply, now transform to logical variables
|
{ // We have matched a double precision multiply, now transform to logical variables
|
||||||
outdoub.initPartial(in.getSize(),reslo,reshi);
|
outdoub.initPartial(in.getSize(),reslo,reshi);
|
||||||
in2.initPartial(in.getSize(),lo2,hi2);
|
in2.initPartial(in.getSize(),lo2,hi2);
|
||||||
|
if (in2.exceedsConstPrecision())
|
||||||
|
return false;
|
||||||
existop = SplitVarnode::prepareBinaryOp(outdoub,in,in2);
|
existop = SplitVarnode::prepareBinaryOp(outdoub,in,in2);
|
||||||
if (existop == (PcodeOp *)0)
|
if (existop == (PcodeOp *)0)
|
||||||
return false;
|
return false;
|
||||||
|
@ -3147,6 +3175,10 @@ int4 RuleDoubleIn::attemptMarking(Funcdata &data,Varnode *vn,PcodeOp *subpieceOp
|
||||||
|
|
||||||
{
|
{
|
||||||
Varnode *whole = subpieceOp->getIn(0);
|
Varnode *whole = subpieceOp->getIn(0);
|
||||||
|
if (whole->isTypeLock()) {
|
||||||
|
if (!whole->getType()->isPrimitiveWhole())
|
||||||
|
return 0; // Don't mark for double precision if not a primitive type
|
||||||
|
}
|
||||||
int4 offset = (int4)subpieceOp->getIn(1)->getOffset();
|
int4 offset = (int4)subpieceOp->getIn(1)->getOffset();
|
||||||
if (offset != vn->getSize()) return 0;
|
if (offset != vn->getSize()) return 0;
|
||||||
if (offset * 2 != whole->getSize()) return 0; // Truncate exactly half
|
if (offset * 2 != whole->getSize()) return 0; // Truncate exactly half
|
||||||
|
|
|
@ -70,6 +70,7 @@ public:
|
||||||
void buildHiFromWhole(Funcdata &data); ///< Rebuild the most significant piece as a CPUI_SUBPIECE of the \b whole
|
void buildHiFromWhole(Funcdata &data); ///< Rebuild the most significant piece as a CPUI_SUBPIECE of the \b whole
|
||||||
PcodeOp *findEarliestSplitPoint(void); ///< Find the earliest definition point of the \b lo and \b hi pieces
|
PcodeOp *findEarliestSplitPoint(void); ///< Find the earliest definition point of the \b lo and \b hi pieces
|
||||||
PcodeOp *findOutExist(void); ///< Find the point at which the output \b whole must exist
|
PcodeOp *findOutExist(void); ///< Find the point at which the output \b whole must exist
|
||||||
|
bool exceedsConstPrecision(void) const; ///< Check if \b this is a constant that exceeds precision limits
|
||||||
static bool adjacentOffsets(Varnode *vn1,Varnode *vn2,uintb size1);
|
static bool adjacentOffsets(Varnode *vn1,Varnode *vn2,uintb size1);
|
||||||
static bool testContiguousPointers(PcodeOp *most,PcodeOp *least,PcodeOp *&first,PcodeOp *&second,AddrSpace *&spc);
|
static bool testContiguousPointers(PcodeOp *most,PcodeOp *least,PcodeOp *&first,PcodeOp *&second,AddrSpace *&spc);
|
||||||
static bool isAddrTiedContiguous(Varnode *lo,Varnode *hi,Address &res);
|
static bool isAddrTiedContiguous(Varnode *lo,Varnode *hi,Address &res);
|
||||||
|
|
|
@ -2065,11 +2065,9 @@ void Heritage::splitJoinRead(Varnode *vn,JoinRecord *joinrec)
|
||||||
|
|
||||||
{
|
{
|
||||||
PcodeOp *op = vn->loneDescend(); // vn isFree, so loneDescend must be non-null
|
PcodeOp *op = vn->loneDescend(); // vn isFree, so loneDescend must be non-null
|
||||||
bool preventConstCollapse = false;
|
bool isPrimitive = true;
|
||||||
if (vn->isTypeLock()) {
|
if (vn->isTypeLock()) {
|
||||||
type_metatype meta = vn->getType()->getMetatype();
|
isPrimitive = vn->getType()->isPrimitiveWhole();
|
||||||
if (meta == TYPE_STRUCT || meta == TYPE_ARRAY)
|
|
||||||
preventConstCollapse = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
vector<Varnode *> lastcombo;
|
vector<Varnode *> lastcombo;
|
||||||
|
@ -2090,10 +2088,13 @@ void Heritage::splitJoinRead(Varnode *vn,JoinRecord *joinrec)
|
||||||
fd->opSetInput(concat,mosthalf,0);
|
fd->opSetInput(concat,mosthalf,0);
|
||||||
fd->opSetInput(concat,leasthalf,1);
|
fd->opSetInput(concat,leasthalf,1);
|
||||||
fd->opInsertBefore(concat,op);
|
fd->opInsertBefore(concat,op);
|
||||||
if (preventConstCollapse)
|
if (isPrimitive) {
|
||||||
|
mosthalf->setPrecisHi(); // Set precision flags to trigger "double precision" rules
|
||||||
|
leasthalf->setPrecisLo();
|
||||||
|
}
|
||||||
|
else {
|
||||||
fd->opMarkNoCollapse(concat);
|
fd->opMarkNoCollapse(concat);
|
||||||
mosthalf->setPrecisHi(); // Set precision flags to trigger "double precision" rules
|
}
|
||||||
leasthalf->setPrecisLo();
|
|
||||||
op = concat; // Keep -op- as the earliest op in the concatenation construction
|
op = concat; // Keep -op- as the earliest op in the concatenation construction
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2118,6 +2119,9 @@ void Heritage::splitJoinWrite(Varnode *vn,JoinRecord *joinrec)
|
||||||
{
|
{
|
||||||
PcodeOp *op = vn->getDef(); // vn cannot be free, either it has def, or it is input
|
PcodeOp *op = vn->getDef(); // vn cannot be free, either it has def, or it is input
|
||||||
BlockBasic *bb = (BlockBasic *)fd->getBasicBlocks().getBlock(0);
|
BlockBasic *bb = (BlockBasic *)fd->getBasicBlocks().getBlock(0);
|
||||||
|
bool isPrimitive = true;
|
||||||
|
if (vn->isTypeLock())
|
||||||
|
isPrimitive = vn->getType()->isPrimitiveWhole();
|
||||||
|
|
||||||
vector<Varnode *> lastcombo;
|
vector<Varnode *> lastcombo;
|
||||||
vector<Varnode *> nextlev;
|
vector<Varnode *> nextlev;
|
||||||
|
@ -2151,8 +2155,10 @@ void Heritage::splitJoinWrite(Varnode *vn,JoinRecord *joinrec)
|
||||||
fd->opSetInput(split,curvn,0);
|
fd->opSetInput(split,curvn,0);
|
||||||
fd->opSetInput(split,fd->newConstant(4,0),1);
|
fd->opSetInput(split,fd->newConstant(4,0),1);
|
||||||
fd->opInsertAfter(split,op);
|
fd->opInsertAfter(split,op);
|
||||||
mosthalf->setPrecisHi(); // Make sure we set the precision flags to trigger "double precision" rules
|
if (isPrimitive) {
|
||||||
leasthalf->setPrecisLo();
|
mosthalf->setPrecisHi(); // Make sure we set the precision flags to trigger "double precision" rules
|
||||||
|
leasthalf->setPrecisLo();
|
||||||
|
}
|
||||||
op = split; // Keep -op- as the latest op in the split construction
|
op = split; // Keep -op- as the latest op in the split construction
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -337,7 +337,7 @@ void DatatypeMatchFilter::decode(Decoder &decoder)
|
||||||
///
|
///
|
||||||
/// Allocate the action object corresponding to the element and configure it.
|
/// Allocate the action object corresponding to the element and configure it.
|
||||||
/// If the next element is not an action, throw an exception.
|
/// If the next element is not an action, throw an exception.
|
||||||
/// \param parser is the stream decoder
|
/// \param decoder is the stream decoder
|
||||||
/// \param res is the resource set for the new action
|
/// \param res is the resource set for the new action
|
||||||
/// \return the new action
|
/// \return the new action
|
||||||
AssignAction *AssignAction::decodeAction(Decoder &decoder,const ParamListStandard *res)
|
AssignAction *AssignAction::decodeAction(Decoder &decoder,const ParamListStandard *res)
|
||||||
|
@ -377,7 +377,7 @@ AssignAction *AssignAction::decodeAction(Decoder &decoder,const ParamListStandar
|
||||||
///
|
///
|
||||||
/// Allocate the sideeffect object corresponding to the element and configure it.
|
/// Allocate the sideeffect object corresponding to the element and configure it.
|
||||||
/// If the next element is not a sideeffect, throw an exception.
|
/// If the next element is not a sideeffect, throw an exception.
|
||||||
/// \param parser is the stream decoder
|
/// \param decoder is the stream decoder
|
||||||
/// \param res is the resource set for the new sideeffect
|
/// \param res is the resource set for the new sideeffect
|
||||||
/// \return the new sideeffect
|
/// \return the new sideeffect
|
||||||
AssignAction *AssignAction::decodeSideeffect(Decoder &decoder,const ParamListStandard *res)
|
AssignAction *AssignAction::decodeSideeffect(Decoder &decoder,const ParamListStandard *res)
|
||||||
|
|
|
@ -286,7 +286,7 @@ class MultiSlotAssign : public AssignAction {
|
||||||
void initializeEntries(void); ///< Cache specific ParamEntry needed by the action
|
void initializeEntries(void); ///< Cache specific ParamEntry needed by the action
|
||||||
public:
|
public:
|
||||||
MultiSlotAssign(const ParamListStandard *res); ///< Constructor for use with decode
|
MultiSlotAssign(const ParamListStandard *res); ///< Constructor for use with decode
|
||||||
MultiSlotAssign(type_class store,bool stack,bool mostSig,bool align,bool justRight,const ParamListStandard *res);
|
MultiSlotAssign(type_class store,bool stack,bool mostSig,bool align,bool justRight,const ParamListStandard *res); ///< Constructor
|
||||||
virtual AssignAction *clone(const ParamListStandard *newResource) const {
|
virtual AssignAction *clone(const ParamListStandard *newResource) const {
|
||||||
return new MultiSlotAssign(resourceType,consumeFromStack,consumeMostSig,enforceAlignment,justifyRight,newResource); }
|
return new MultiSlotAssign(resourceType,consumeFromStack,consumeMostSig,enforceAlignment,justifyRight,newResource); }
|
||||||
virtual uint4 assignAddress(Datatype *dt,const PrototypePieces &proto,int4 pos,TypeFactory &tlist,
|
virtual uint4 assignAddress(Datatype *dt,const PrototypePieces &proto,int4 pos,TypeFactory &tlist,
|
||||||
|
@ -304,7 +304,7 @@ class MultiMemberAssign : public AssignAction {
|
||||||
bool consumeFromStack; ///< True if resources should be consumed from the stack
|
bool consumeFromStack; ///< True if resources should be consumed from the stack
|
||||||
bool consumeMostSig; ///< True if resources are consumed starting with most significant bytes
|
bool consumeMostSig; ///< True if resources are consumed starting with most significant bytes
|
||||||
public:
|
public:
|
||||||
MultiMemberAssign(type_class store,bool stack,bool mostSig,const ParamListStandard *res);
|
MultiMemberAssign(type_class store,bool stack,bool mostSig,const ParamListStandard *res); ///< Constructor
|
||||||
virtual AssignAction *clone(const ParamListStandard *newResource) const {
|
virtual AssignAction *clone(const ParamListStandard *newResource) const {
|
||||||
return new MultiMemberAssign(resourceType,consumeFromStack,consumeMostSig,newResource); }
|
return new MultiMemberAssign(resourceType,consumeFromStack,consumeMostSig,newResource); }
|
||||||
virtual uint4 assignAddress(Datatype *dt,const PrototypePieces &proto,int4 pos,TypeFactory &tlist,
|
virtual uint4 assignAddress(Datatype *dt,const PrototypePieces &proto,int4 pos,TypeFactory &tlist,
|
||||||
|
|
|
@ -476,6 +476,23 @@ void Datatype::encodeRef(Encoder &encoder) const
|
||||||
encode(encoder);
|
encode(encoder);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// If \b this has no component data-types, return \b true.
|
||||||
|
/// If \b this has only a single primitive component filling the whole data-type, also return \b true.
|
||||||
|
/// \return \b true if \b this data-type is made up of a single primitive
|
||||||
|
bool Datatype::isPrimitiveWhole(void) const
|
||||||
|
|
||||||
|
{
|
||||||
|
if (!isPieceStructured()) return true;
|
||||||
|
if (metatype == TYPE_ARRAY || metatype == TYPE_STRUCT) {
|
||||||
|
if (numDepend() > 0) {
|
||||||
|
Datatype *component = getDepend(0);
|
||||||
|
if (component->getSize() == getSize())
|
||||||
|
return component->isPrimitiveWhole();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/// Called only if the \b typedefImm field is non-null. Encode the data-type to the
|
/// Called only if the \b typedefImm field is non-null. Encode the data-type to the
|
||||||
/// stream as a simple \<typedef> element including only the names and ids of \b this and
|
/// stream as a simple \<typedef> element including only the names and ids of \b this and
|
||||||
/// the data-type it typedefs.
|
/// the data-type it typedefs.
|
||||||
|
|
|
@ -278,6 +278,7 @@ public:
|
||||||
int4 typeOrderBool(const Datatype &op) const; ///< Order \b this with -op-, treating \e bool data-type as special
|
int4 typeOrderBool(const Datatype &op) const; ///< Order \b this with -op-, treating \e bool data-type as special
|
||||||
void encodeRef(Encoder &encoder) const; ///< Encode a reference of \b this to a stream
|
void encodeRef(Encoder &encoder) const; ///< Encode a reference of \b this to a stream
|
||||||
bool isPieceStructured(void) const; ///< Does \b this data-type consist of separate pieces?
|
bool isPieceStructured(void) const; ///< Does \b this data-type consist of separate pieces?
|
||||||
|
bool isPrimitiveWhole(void) const; ///< Is \b this made up of a single primitive
|
||||||
static uint4 encodeIntegerFormat(const string &val);
|
static uint4 encodeIntegerFormat(const string &val);
|
||||||
static string decodeIntegerFormat(uint4 val);
|
static string decodeIntegerFormat(uint4 val);
|
||||||
};
|
};
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue