Skip to content
Snippets Groups Projects
Commit 6c52f896 authored by John Kessenich's avatar John Kessenich
Browse files

PP: Remove second parsing of numbers recorded in macros; save/use original.

This partly addresses #1228 and #234 by reducing usage of strtod (or atof).
There is now only place to parse a floating-point number.
parent 1ea1b13f
No related branches found
No related tags found
No related merge requests found
......@@ -92,13 +92,16 @@ namespace glslang {
class TPpToken {
public:
TPpToken() : space(false), i64val(0)
TPpToken() { clear(); }
void clear()
{
space = false;
i64val = 0;
loc.init();
name[0] = 0;
}
// This is used for comparing macro definitions, so checks what is relevant for that.
// Used for comparing macro definitions, so checks what is relevant for that.
bool operator==(const TPpToken& right)
{
return space == right.space &&
......@@ -108,15 +111,17 @@ public:
bool operator!=(const TPpToken& right) { return ! operator==(right); }
TSourceLoc loc;
bool space; // true if a space (for white space or a removed comment) should also be recognized, in front of the token returned
// True if a space (for white space or a removed comment) should also be
// recognized, in front of the token returned:
bool space;
// Numeric value of the token:
union {
int ival;
double dval;
long long i64val;
};
char name[MaxTokenLength + 1];
// Text string of the token:
char name[MaxTokenLength + 1];
};
class TStringAtomMap {
......
......@@ -97,6 +97,56 @@ NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
namespace glslang {
namespace {
// When recording (and playing back) should the backing name string
// be saved (restored)?
bool SaveName(int atom)
{
switch (atom) {
case PpAtomIdentifier:
case PpAtomConstString:
case PpAtomConstInt:
case PpAtomConstUint:
case PpAtomConstInt64:
case PpAtomConstUint64:
#ifdef AMD_EXTENSIONS
case PpAtomConstInt16:
case PpAtomConstUint16:
#endif
case PpAtomConstFloat:
case PpAtomConstDouble:
case PpAtomConstFloat16:
return true;
default:
return false;
}
}
// When recording (and playing back) should the numeric value
// be saved (restored)?
bool SaveValue(int atom)
{
switch (atom) {
case PpAtomConstInt:
case PpAtomConstUint:
case PpAtomConstInt64:
case PpAtomConstUint64:
#ifdef AMD_EXTENSIONS
case PpAtomConstInt16:
case PpAtomConstUint16:
#endif
case PpAtomConstFloat:
case PpAtomConstDouble:
case PpAtomConstFloat16:
return true;
default:
return false;
}
}
}
// push onto back of stream
void TPpContext::TokenStream::putSubtoken(char subtoken)
{
......@@ -121,42 +171,25 @@ void TPpContext::TokenStream::ungetSubtoken()
// Add a complete token (including backing string) to the end of a list
// for later playback.
void TPpContext::TokenStream::putToken(int token, TPpToken* ppToken)
void TPpContext::TokenStream::putToken(int atom, TPpToken* ppToken)
{
const char* s;
char* str = NULL;
// save the atom
assert((atom & ~0xff) == 0);
putSubtoken(static_cast<char>(atom));
assert((token & ~0xff) == 0);
putSubtoken(static_cast<char>(token));
switch (token) {
case PpAtomIdentifier:
case PpAtomConstString:
s = ppToken->name;
// save the backing name string
if (SaveName(atom)) {
const char* s = ppToken->name;
while (*s)
putSubtoken(*s++);
putSubtoken(0);
break;
case PpAtomConstInt:
case PpAtomConstUint:
case PpAtomConstInt64:
case PpAtomConstUint64:
#ifdef AMD_EXTENSIONS
case PpAtomConstInt16:
case PpAtomConstUint16:
#endif
case PpAtomConstFloat:
case PpAtomConstDouble:
case PpAtomConstFloat16:
str = ppToken->name;
while (*str) {
putSubtoken(*str);
str++;
}
putSubtoken(0);
break;
default:
break;
}
// save the numeric value
if (SaveValue(atom)) {
const char* n = reinterpret_cast<const char*>(&ppToken->i64val);
for (int i = 0; i < sizeof(ppToken->i64val); ++i)
putSubtoken(*n++);
}
}
......@@ -164,38 +197,19 @@ void TPpContext::TokenStream::putToken(int token, TPpToken* ppToken)
// (Not the source stream, but a stream used to hold a tokenized macro).
int TPpContext::TokenStream::getToken(TParseContextBase& parseContext, TPpToken *ppToken)
{
int len;
int ch;
// get the atom
int atom = getSubtoken();
if (atom == EndOfInput)
return atom;
int subtoken = getSubtoken();
// init the token
ppToken->clear();
ppToken->loc = parseContext.getCurrentLoc();
switch (subtoken) {
case '#':
// Check for ##, unless the current # is the last character
if (current < data.size()) {
if (getSubtoken() == '#') {
parseContext.requireProfile(ppToken->loc, ~EEsProfile, "token pasting (##)");
parseContext.profileRequires(ppToken->loc, ~EEsProfile, 130, 0, "token pasting (##)");
subtoken = PpAtomPaste;
} else
ungetSubtoken();
}
break;
case PpAtomConstString:
case PpAtomIdentifier:
case PpAtomConstFloat:
case PpAtomConstDouble:
case PpAtomConstFloat16:
case PpAtomConstInt:
case PpAtomConstUint:
case PpAtomConstInt64:
case PpAtomConstUint64:
#ifdef AMD_EXTENSIONS
case PpAtomConstInt16:
case PpAtomConstUint16:
#endif
len = 0;
ch = getSubtoken();
// get the backing name string
if (SaveName(atom)) {
int ch = getSubtoken();
int len = 0;
while (ch != 0 && ch != EndOfInput) {
if (len < MaxTokenLength) {
ppToken->name[len] = (char)ch;
......@@ -207,63 +221,28 @@ int TPpContext::TokenStream::getToken(TParseContextBase& parseContext, TPpToken
}
}
ppToken->name[len] = 0;
}
switch (subtoken) {
case PpAtomIdentifier:
break;
case PpAtomConstString:
break;
case PpAtomConstFloat:
case PpAtomConstDouble:
case PpAtomConstFloat16:
ppToken->dval = atof(ppToken->name);
break;
case PpAtomConstInt:
#ifdef AMD_EXTENSIONS
case PpAtomConstInt16:
#endif
if (len > 0 && ppToken->name[0] == '0') {
if (len > 1 && (ppToken->name[1] == 'x' || ppToken->name[1] == 'X'))
ppToken->ival = (int)strtol(ppToken->name, 0, 16);
else
ppToken->ival = (int)strtol(ppToken->name, 0, 8);
} else
ppToken->ival = atoi(ppToken->name);
break;
case PpAtomConstUint:
#ifdef AMD_EXTENSIONS
case PpAtomConstUint16:
#endif
if (len > 0 && ppToken->name[0] == '0') {
if (len > 1 && (ppToken->name[1] == 'x' || ppToken->name[1] == 'X'))
ppToken->ival = (int)strtoul(ppToken->name, 0, 16);
else
ppToken->ival = (int)strtoul(ppToken->name, 0, 8);
} else
ppToken->ival = (int)strtoul(ppToken->name, 0, 10);
break;
case PpAtomConstInt64:
if (len > 0 && ppToken->name[0] == '0') {
if (len > 1 && (ppToken->name[1] == 'x' || ppToken->name[1] == 'X'))
ppToken->i64val = strtoll(ppToken->name, nullptr, 16);
else
ppToken->i64val = strtoll(ppToken->name, nullptr, 8);
} else
ppToken->i64val = atoll(ppToken->name);
break;
case PpAtomConstUint64:
if (len > 0 && ppToken->name[0] == '0') {
if (len > 1 && (ppToken->name[1] == 'x' || ppToken->name[1] == 'X'))
ppToken->i64val = (long long)strtoull(ppToken->name, nullptr, 16);
else
ppToken->i64val = (long long)strtoull(ppToken->name, nullptr, 8);
// Check for ##, unless the current # is the last character
if (atom == '#') {
if (current < data.size()) {
if (getSubtoken() == '#') {
parseContext.requireProfile(ppToken->loc, ~EEsProfile, "token pasting (##)");
parseContext.profileRequires(ppToken->loc, ~EEsProfile, 130, 0, "token pasting (##)");
atom = PpAtomPaste;
} else
ppToken->i64val = (long long)strtoull(ppToken->name, 0, 10);
break;
ungetSubtoken();
}
}
return subtoken;
// get the numeric value
if (SaveValue(atom)) {
char* n = reinterpret_cast<char*>(&ppToken->i64val);
for (int i = 0; i < sizeof(ppToken->i64val); ++i)
*n++ = getSubtoken();
}
return atom;
}
// We are pasting if
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment