From: John Kessenich Date: Fri, 25 May 2018 00:24:06 +0000 (-0600) Subject: PP: Remove second parsing of numbers recorded in macros; save/use original. X-Git-Tag: upstream/11.4.0~743^2~1 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=6c52f8968c169598419b5dd433a345979a2fe1e5;p=platform%2Fupstream%2Fglslang.git 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. --- diff --git a/glslang/MachineIndependent/preprocessor/PpContext.h b/glslang/MachineIndependent/preprocessor/PpContext.h old mode 100644 new mode 100755 index 854bbba..04d23b2 --- a/glslang/MachineIndependent/preprocessor/PpContext.h +++ b/glslang/MachineIndependent/preprocessor/PpContext.h @@ -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 { diff --git a/glslang/MachineIndependent/preprocessor/PpTokens.cpp b/glslang/MachineIndependent/preprocessor/PpTokens.cpp old mode 100644 new mode 100755 index 31e0d1f..d8088e7 --- a/glslang/MachineIndependent/preprocessor/PpTokens.cpp +++ b/glslang/MachineIndependent/preprocessor/PpTokens.cpp @@ -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(atom)); - assert((token & ~0xff) == 0); - putSubtoken(static_cast(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(&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(&ppToken->i64val); + for (int i = 0; i < sizeof(ppToken->i64val); ++i) + *n++ = getSubtoken(); + } + + return atom; } // We are pasting if