summaryrefslogtreecommitdiffstats
path: root/chromium/third_party/glslang/src/glslang/MachineIndependent/preprocessor
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/third_party/glslang/src/glslang/MachineIndependent/preprocessor')
-rw-r--r--chromium/third_party/glslang/src/glslang/MachineIndependent/preprocessor/Pp.cpp1151
-rw-r--r--chromium/third_party/glslang/src/glslang/MachineIndependent/preprocessor/PpAtom.cpp192
-rw-r--r--chromium/third_party/glslang/src/glslang/MachineIndependent/preprocessor/PpContext.cpp122
-rw-r--r--chromium/third_party/glslang/src/glslang/MachineIndependent/preprocessor/PpContext.h570
-rw-r--r--chromium/third_party/glslang/src/glslang/MachineIndependent/preprocessor/PpMemory.cpp162
-rw-r--r--chromium/third_party/glslang/src/glslang/MachineIndependent/preprocessor/PpScanner.cpp778
-rw-r--r--chromium/third_party/glslang/src/glslang/MachineIndependent/preprocessor/PpSymbols.cpp135
-rw-r--r--chromium/third_party/glslang/src/glslang/MachineIndependent/preprocessor/PpTokens.cpp278
-rw-r--r--chromium/third_party/glslang/src/glslang/MachineIndependent/preprocessor/PpTokens.h171
9 files changed, 3559 insertions, 0 deletions
diff --git a/chromium/third_party/glslang/src/glslang/MachineIndependent/preprocessor/Pp.cpp b/chromium/third_party/glslang/src/glslang/MachineIndependent/preprocessor/Pp.cpp
new file mode 100644
index 00000000000..35097588c43
--- /dev/null
+++ b/chromium/third_party/glslang/src/glslang/MachineIndependent/preprocessor/Pp.cpp
@@ -0,0 +1,1151 @@
+//
+//Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
+//Copyright (C) 2013 LunarG, Inc.
+//All rights reserved.
+//
+//Redistribution and use in source and binary forms, with or without
+//modification, are permitted provided that the following conditions
+//are met:
+//
+// Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+//
+// Neither the name of 3Dlabs Inc. Ltd. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+//"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+//LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+//FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+//COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+//INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+//BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+//LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+//CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+//LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+//ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+//POSSIBILITY OF SUCH DAMAGE.
+//
+/****************************************************************************\
+Copyright (c) 2002, NVIDIA Corporation.
+
+NVIDIA Corporation("NVIDIA") supplies this software to you in
+consideration of your agreement to the following terms, and your use,
+installation, modification or redistribution of this NVIDIA software
+constitutes acceptance of these terms. If you do not agree with these
+terms, please do not use, install, modify or redistribute this NVIDIA
+software.
+
+In consideration of your agreement to abide by the following terms, and
+subject to these terms, NVIDIA grants you a personal, non-exclusive
+license, under NVIDIA's copyrights in this original NVIDIA software (the
+"NVIDIA Software"), to use, reproduce, modify and redistribute the
+NVIDIA Software, with or without modifications, in source and/or binary
+forms; provided that if you redistribute the NVIDIA Software, you must
+retain the copyright notice of NVIDIA, this notice and the following
+text and disclaimers in all such redistributions of the NVIDIA Software.
+Neither the name, trademarks, service marks nor logos of NVIDIA
+Corporation may be used to endorse or promote products derived from the
+NVIDIA Software without specific prior written permission from NVIDIA.
+Except as expressly stated in this notice, no other rights or licenses
+express or implied, are granted by NVIDIA herein, including but not
+limited to any patent rights that may be infringed by your derivative
+works or by other works in which the NVIDIA Software may be
+incorporated. No hardware is licensed hereunder.
+
+THE NVIDIA SOFTWARE IS BEING PROVIDED ON AN "AS IS" BASIS, WITHOUT
+WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED,
+INCLUDING WITHOUT LIMITATION, WARRANTIES OR CONDITIONS OF TITLE,
+NON-INFRINGEMENT, MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR
+ITS USE AND OPERATION EITHER ALONE OR IN COMBINATION WITH OTHER
+PRODUCTS.
+
+IN NO EVENT SHALL NVIDIA BE LIABLE FOR ANY SPECIAL, INDIRECT,
+INCIDENTAL, EXEMPLARY, CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+TO, LOST PROFITS; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) OR ARISING IN ANY WAY
+OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION OF THE
+NVIDIA SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT,
+TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF
+NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+\****************************************************************************/
+//
+// cpp.c
+//
+
+#define _CRT_SECURE_NO_WARNINGS
+
+#include <stdarg.h>
+#include <stdio.h>
+#include <sstream>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+
+#include "PpContext.h"
+#include "PpTokens.h"
+
+namespace glslang {
+
+int TPpContext::InitCPP()
+{
+ pool = mem_CreatePool(0, 0);
+
+ return 1;
+}
+
+// Handle #define
+int TPpContext::CPPdefine(TPpToken* ppToken)
+{
+ MacroSymbol mac;
+ Symbol *symb;
+
+ // get macro name
+ int token = scanToken(ppToken);
+ if (token != PpAtomIdentifier) {
+ parseContext.ppError(ppToken->loc, "must be followed by macro name", "#define", "");
+ return token;
+ }
+ if (ppToken->loc.string >= 0) {
+ // We are in user code; check for reserved name use:
+ parseContext.reservedPpErrorCheck(ppToken->loc, ppToken->name, "#define");
+ }
+
+ // save the original atom
+ const int defAtom = ppToken->atom;
+
+ // gather parameters to the macro, between (...)
+ token = scanToken(ppToken);
+ if (token == '(' && ! ppToken->space) {
+ int argc = 0;
+ int args[maxMacroArgs];
+ do {
+ token = scanToken(ppToken);
+ if (argc == 0 && token == ')')
+ break;
+ if (token != PpAtomIdentifier) {
+ parseContext.ppError(ppToken->loc, "bad argument", "#define", "");
+
+ return token;
+ }
+ // check for duplication of parameter name
+ bool duplicate = false;
+ for (int a = 0; a < argc; ++a) {
+ if (args[a] == ppToken->atom) {
+ parseContext.ppError(ppToken->loc, "duplicate macro parameter", "#define", "");
+ duplicate = true;
+ break;
+ }
+ }
+ if (! duplicate) {
+ if (argc < maxMacroArgs)
+ args[argc++] = ppToken->atom;
+ else
+ parseContext.ppError(ppToken->loc, "too many macro parameters", "#define", "");
+ }
+ token = scanToken(ppToken);
+ } while (token == ',');
+ if (token != ')') {
+ parseContext.ppError(ppToken->loc, "missing parenthesis", "#define", "");
+
+ return token;
+ }
+ mac.argc = argc;
+ mac.args = (int*)mem_Alloc(pool, argc * sizeof(int));
+ memcpy(mac.args, args, argc * sizeof(int));
+ token = scanToken(ppToken);
+ }
+
+ // record the definition of the macro
+ TSourceLoc defineLoc = ppToken->loc; // because ppToken is going to go to the next line before we report errors
+ mac.body = new TokenStream;
+ while (token != '\n' && token != EndOfInput) {
+ RecordToken(mac.body, token, ppToken);
+ token = scanToken(ppToken);
+ if (token != '\n' && ppToken->space)
+ RecordToken(mac.body, ' ', ppToken);
+ }
+
+ // check for duplicate definition
+ symb = LookUpSymbol(defAtom);
+ if (symb) {
+ if (! symb->mac.undef) {
+ // Already defined -- need to make sure they are identical:
+ // "Two replacement lists are identical if and only if the preprocessing tokens in both have the same number,
+ // ordering, spelling, and white-space separation, where all white-space separations are considered identical."
+ if (symb->mac.argc != mac.argc)
+ parseContext.ppError(defineLoc, "Macro redefined; different number of arguments:", "#define", GetAtomString(defAtom));
+ else {
+ for (int argc = 0; argc < mac.argc; argc++) {
+ if (symb->mac.args[argc] != mac.args[argc])
+ parseContext.ppError(defineLoc, "Macro redefined; different argument names:", "#define", GetAtomString(defAtom));
+ }
+ RewindTokenStream(symb->mac.body);
+ RewindTokenStream(mac.body);
+ int newToken;
+ do {
+ int oldToken;
+ TPpToken oldPpToken;
+ TPpToken newPpToken;
+ oldToken = ReadToken(symb->mac.body, &oldPpToken);
+ newToken = ReadToken(mac.body, &newPpToken);
+ if (oldToken != newToken || oldPpToken != newPpToken) {
+ parseContext.ppError(defineLoc, "Macro redefined; different substitutions:", "#define", GetAtomString(defAtom));
+ break;
+ }
+ } while (newToken > 0);
+ }
+ }
+ } else
+ symb = AddSymbol(defAtom);
+
+ delete symb->mac.body;
+ symb->mac = mac;
+
+ return '\n';
+}
+
+// Handle #undef
+int TPpContext::CPPundef(TPpToken* ppToken)
+{
+ int token = scanToken(ppToken);
+ Symbol *symb;
+ if (token != PpAtomIdentifier) {
+ parseContext.ppError(ppToken->loc, "must be followed by macro name", "#undef", "");
+
+ return token;
+ }
+
+ parseContext.reservedPpErrorCheck(ppToken->loc, ppToken->name, "#undef");
+
+ symb = LookUpSymbol(ppToken->atom);
+ if (symb) {
+ symb->mac.undef = 1;
+ }
+ token = scanToken(ppToken);
+ if (token != '\n')
+ parseContext.ppError(ppToken->loc, "can only be followed by a single macro name", "#undef", "");
+
+ return token;
+}
+
+// Handle #else
+/* Skip forward to appropriate spot. This is used both
+** to skip to a #endif after seeing an #else, AND to skip to a #else,
+** #elif, or #endif after a #if/#ifdef/#ifndef/#elif test was false.
+*/
+int TPpContext::CPPelse(int matchelse, TPpToken* ppToken)
+{
+ int atom;
+ int depth = 0;
+ int token = scanToken(ppToken);
+
+ while (token != EndOfInput) {
+ if (token != '#') {
+ while (token != '\n' && token != EndOfInput)
+ token = scanToken(ppToken);
+
+ if (token == EndOfInput)
+ return token;
+
+ token = scanToken(ppToken);
+ continue;
+ }
+
+ if ((token = scanToken(ppToken)) != PpAtomIdentifier)
+ continue;
+
+ atom = ppToken->atom;
+ if (atom == PpAtomIf || atom == PpAtomIfdef || atom == PpAtomIfndef) {
+ depth++;
+ ifdepth++;
+ elsetracker++;
+ } else if (atom == PpAtomEndif) {
+ token = extraTokenCheck(atom, ppToken, scanToken(ppToken));
+ elseSeen[elsetracker] = false;
+ --elsetracker;
+ if (depth == 0) {
+ // found the #endif we are looking for
+ if (ifdepth)
+ --ifdepth;
+ break;
+ }
+ --depth;
+ --ifdepth;
+ } else if (matchelse && depth == 0) {
+ if (atom == PpAtomElse) {
+ elseSeen[elsetracker] = true;
+ token = extraTokenCheck(atom, ppToken, scanToken(ppToken));
+ // found the #else we are looking for
+ break;
+ } else if (atom == PpAtomElif) {
+ if (elseSeen[elsetracker])
+ parseContext.ppError(ppToken->loc, "#elif after #else", "#elif", "");
+ /* we decrement ifdepth here, because CPPif will increment
+ * it and we really want to leave it alone */
+ if (ifdepth) {
+ --ifdepth;
+ elseSeen[elsetracker] = false;
+ --elsetracker;
+ }
+
+ return CPPif(ppToken);
+ }
+ } else if (atom == PpAtomElse) {
+ if (elseSeen[elsetracker])
+ parseContext.ppError(ppToken->loc, "#else after #else", "#else", "");
+ else
+ elseSeen[elsetracker] = true;
+ token = extraTokenCheck(atom, ppToken, scanToken(ppToken));
+ } else if (atom == PpAtomElif) {
+ if (elseSeen[elsetracker])
+ parseContext.ppError(ppToken->loc, "#elif after #else", "#elif", "");
+ }
+ }
+
+ return token;
+}
+
+// Call when there should be no more tokens left on a line.
+int TPpContext::extraTokenCheck(int atom, TPpToken* ppToken, int token)
+{
+ if (token != '\n' && token != EndOfInput) {
+ static const char* message = "unexpected tokens following directive";
+
+ const char* label;
+ if (atom == PpAtomElse)
+ label = "#else";
+ else if (atom == PpAtomElif)
+ label = "#elif";
+ else if (atom == PpAtomEndif)
+ label = "#endif";
+ else if (atom == PpAtomIf)
+ label = "#if";
+ else if (atom == PpAtomLine)
+ label = "#line";
+ else
+ label = "";
+
+ if (parseContext.relaxedErrors())
+ parseContext.ppWarn(ppToken->loc, message, label, "");
+ else
+ parseContext.ppError(ppToken->loc, message, label, "");
+
+ while (token != '\n' && token != EndOfInput)
+ token = scanToken(ppToken);
+ }
+
+ return token;
+}
+
+enum eval_prec {
+ MIN_PRECEDENCE,
+ COND, LOGOR, LOGAND, OR, XOR, AND, EQUAL, RELATION, SHIFT, ADD, MUL, UNARY,
+ MAX_PRECEDENCE
+};
+
+namespace {
+
+ int op_logor(int a, int b) { return a || b; }
+ int op_logand(int a, int b) { return a && b; }
+ int op_or(int a, int b) { return a | b; }
+ int op_xor(int a, int b) { return a ^ b; }
+ int op_and(int a, int b) { return a & b; }
+ int op_eq(int a, int b) { return a == b; }
+ int op_ne(int a, int b) { return a != b; }
+ int op_ge(int a, int b) { return a >= b; }
+ int op_le(int a, int b) { return a <= b; }
+ int op_gt(int a, int b) { return a > b; }
+ int op_lt(int a, int b) { return a < b; }
+ int op_shl(int a, int b) { return a << b; }
+ int op_shr(int a, int b) { return a >> b; }
+ int op_add(int a, int b) { return a + b; }
+ int op_sub(int a, int b) { return a - b; }
+ int op_mul(int a, int b) { return a * b; }
+ int op_div(int a, int b) { return a / b; }
+ int op_mod(int a, int b) { return a % b; }
+ int op_pos(int a) { return a; }
+ int op_neg(int a) { return -a; }
+ int op_cmpl(int a) { return ~a; }
+ int op_not(int a) { return !a; }
+
+};
+
+struct TBinop {
+ int token, precedence, (*op)(int, int);
+} binop[] = {
+ { PpAtomOr, LOGOR, op_logor },
+ { PpAtomAnd, LOGAND, op_logand },
+ { '|', OR, op_or },
+ { '^', XOR, op_xor },
+ { '&', AND, op_and },
+ { PpAtomEQ, EQUAL, op_eq },
+ { PpAtomNE, EQUAL, op_ne },
+ { '>', RELATION, op_gt },
+ { PpAtomGE, RELATION, op_ge },
+ { '<', RELATION, op_lt },
+ { PpAtomLE, RELATION, op_le },
+ { PpAtomLeft, SHIFT, op_shl },
+ { PpAtomRight, SHIFT, op_shr },
+ { '+', ADD, op_add },
+ { '-', ADD, op_sub },
+ { '*', MUL, op_mul },
+ { '/', MUL, op_div },
+ { '%', MUL, op_mod },
+};
+
+struct TUnop {
+ int token, (*op)(int);
+} unop[] = {
+ { '+', op_pos },
+ { '-', op_neg },
+ { '~', op_cmpl },
+ { '!', op_not },
+};
+
+#define NUM_ELEMENTS(A) (sizeof(A) / sizeof(A[0]))
+
+int TPpContext::eval(int token, int precedence, bool shortCircuit, int& res, bool& err, TPpToken* ppToken)
+{
+ TSourceLoc loc = ppToken->loc; // because we sometimes read the newline before reporting the error
+ if (token == PpAtomIdentifier) {
+ if (ppToken->atom == PpAtomDefined) {
+ bool needclose = 0;
+ token = scanToken(ppToken);
+ if (token == '(') {
+ needclose = true;
+ token = scanToken(ppToken);
+ }
+ if (token != PpAtomIdentifier) {
+ parseContext.ppError(loc, "incorrect directive, expected identifier", "preprocessor evaluation", "");
+ err = true;
+ res = 0;
+
+ return token;
+ }
+ Symbol* s = LookUpSymbol(ppToken->atom);
+ res = s ? ! s->mac.undef : 0;
+ token = scanToken(ppToken);
+ if (needclose) {
+ if (token != ')') {
+ parseContext.ppError(loc, "expected ')'", "preprocessor evaluation", "");
+ err = true;
+ res = 0;
+
+ return token;
+ }
+ token = scanToken(ppToken);
+ }
+ } else {
+ token = evalToToken(token, shortCircuit, res, err, ppToken);
+ return eval(token, precedence, shortCircuit, res, err, ppToken);
+ }
+ } else if (token == PpAtomConstInt) {
+ res = ppToken->ival;
+ token = scanToken(ppToken);
+ } else if (token == '(') {
+ token = scanToken(ppToken);
+ token = eval(token, MIN_PRECEDENCE, shortCircuit, res, err, ppToken);
+ if (! err) {
+ if (token != ')') {
+ parseContext.ppError(loc, "expected ')'", "preprocessor evaluation", "");
+ err = true;
+ res = 0;
+
+ return token;
+ }
+ token = scanToken(ppToken);
+ }
+ } else {
+ int op = NUM_ELEMENTS(unop) - 1;
+ for (; op >= 0; op--) {
+ if (unop[op].token == token)
+ break;
+ }
+ if (op >= 0) {
+ token = scanToken(ppToken);
+ token = eval(token, UNARY, shortCircuit, res, err, ppToken);
+ res = unop[op].op(res);
+ } else {
+ parseContext.ppError(loc, "bad expression", "preprocessor evaluation", "");
+ err = true;
+ res = 0;
+
+ return token;
+ }
+ }
+
+ token = evalToToken(token, shortCircuit, res, err, ppToken);
+
+ // Perform evaluation of binary operation, if there is one, otherwise we are done.
+ while (! err) {
+ if (token == ')' || token == '\n')
+ break;
+ int op;
+ for (op = NUM_ELEMENTS(binop) - 1; op >= 0; op--) {
+ if (binop[op].token == token)
+ break;
+ }
+ if (op < 0 || binop[op].precedence <= precedence)
+ break;
+ int leftSide = res;
+
+ // Setup short-circuiting, needed for ES, unless already in a short circuit.
+ // (Once in a short-circuit, can't turn off again, until that whole subexpression is done.
+ if (! shortCircuit) {
+ if ((token == PpAtomOr && leftSide == 1) ||
+ (token == PpAtomAnd && leftSide == 0))
+ shortCircuit = true;
+ }
+
+ token = scanToken(ppToken);
+ token = eval(token, binop[op].precedence, shortCircuit, res, err, ppToken);
+
+ if (binop[op].op == op_div || binop[op].op == op_mod) {
+ if (res == 0) {
+ parseContext.ppError(loc, "division by 0", "preprocessor evaluation", "");
+ res = 1;
+ }
+ }
+ res = binop[op].op(leftSide, res);
+ }
+
+ return token;
+}
+
+// Expand macros, skipping empty expansions, to get to the first real token in those expansions.
+int TPpContext::evalToToken(int token, bool shortCircuit, int& res, bool& err, TPpToken* ppToken)
+{
+ while (token == PpAtomIdentifier && ppToken->atom != PpAtomDefined) {
+ int macroReturn = MacroExpand(ppToken->atom, ppToken, true, false);
+ if (macroReturn == 0) {
+ parseContext.ppError(ppToken->loc, "can't evaluate expression", "preprocessor evaluation", "");
+ err = true;
+ res = 0;
+ token = scanToken(ppToken);
+ break;
+ }
+ if (macroReturn == -1) {
+ if (! shortCircuit && parseContext.profile == EEsProfile) {
+ const char* message = "undefined macro in expression not allowed in es profile";
+ if (parseContext.relaxedErrors())
+ parseContext.ppWarn(ppToken->loc, message, "preprocessor evaluation", ppToken->name);
+ else
+ parseContext.ppError(ppToken->loc, message, "preprocessor evaluation", ppToken->name);
+ }
+ }
+ token = scanToken(ppToken);
+ }
+
+ return token;
+}
+
+// Handle #if
+int TPpContext::CPPif(TPpToken* ppToken)
+{
+ int token = scanToken(ppToken);
+ elsetracker++;
+ ifdepth++;
+ if (ifdepth > maxIfNesting) {
+ parseContext.ppError(ppToken->loc, "maximum nesting depth exceeded", "#if", "");
+ return 0;
+ }
+ int res = 0;
+ bool err = false;
+ token = eval(token, MIN_PRECEDENCE, false, res, err, ppToken);
+ token = extraTokenCheck(PpAtomIf, ppToken, token);
+ if (!res && !err)
+ token = CPPelse(1, ppToken);
+
+ return token;
+}
+
+// Handle #ifdef
+int TPpContext::CPPifdef(int defined, TPpToken* ppToken)
+{
+ int token = scanToken(ppToken);
+ int name = ppToken->atom;
+ if (++ifdepth > maxIfNesting) {
+ parseContext.ppError(ppToken->loc, "maximum nesting depth exceeded", "#ifdef", "");
+ return 0;
+ }
+ elsetracker++;
+ if (token != PpAtomIdentifier) {
+ if (defined)
+ parseContext.ppError(ppToken->loc, "must be followed by macro name", "#ifdef", "");
+ else
+ parseContext.ppError(ppToken->loc, "must be followed by macro name", "#ifndef", "");
+ } else {
+ Symbol *s = LookUpSymbol(name);
+ token = scanToken(ppToken);
+ if (token != '\n') {
+ parseContext.ppError(ppToken->loc, "unexpected tokens following #ifdef directive - expected a newline", "#ifdef", "");
+ while (token != '\n' && token != EndOfInput)
+ token = scanToken(ppToken);
+ }
+ if (((s && !s->mac.undef) ? 1 : 0) != defined)
+ token = CPPelse(1, ppToken);
+ }
+
+ return token;
+}
+
+// Handle #include
+int TPpContext::CPPinclude(TPpToken* ppToken)
+{
+ const TSourceLoc directiveLoc = ppToken->loc;
+ int token = scanToken(ppToken);
+ if (token != PpAtomConstString) {
+ // TODO: handle angle brackets.
+ parseContext.ppError(directiveLoc, "must be followed by a file designation", "#include", "");
+ } else {
+ // Make a copy of the name because it will be overwritten by the next token scan.
+ const std::string filename = ppToken->name;
+ token = scanToken(ppToken);
+ if (token != '\n' && token != EndOfInput) {
+ parseContext.ppError(ppToken->loc, "extra content after file designation", "#include", "");
+ } else {
+ TShader::Includer::IncludeResult* res = includer.include(filename.c_str(), TShader::Includer::EIncludeRelative, currentSourceFile.c_str(), includeStack.size() + 1);
+ if (res && !res->file_name.empty()) {
+ if (res->file_data && res->file_length) {
+ const bool forNextLine = parseContext.lineDirectiveShouldSetNextLine();
+ std::ostringstream prologue;
+ std::ostringstream epilogue;
+ prologue << "#line " << forNextLine << " " << "\"" << res->file_name << "\"\n";
+ epilogue << (res->file_data[res->file_length - 1] == '\n'? "" : "\n") << "#line " << directiveLoc.line + forNextLine << " " << directiveLoc.getStringNameOrNum() << "\n";
+ pushInput(new TokenizableIncludeFile(directiveLoc, prologue.str(), res, epilogue.str(), this));
+ }
+ // At EOF, there's no "current" location anymore.
+ if (token != EndOfInput) parseContext.setCurrentColumn(0);
+ // Don't accidentally return EndOfInput, which will end all preprocessing.
+ return '\n';
+ } else {
+ std::string message =
+ res ? std::string(res->file_data, res->file_length)
+ : std::string("Could not process include directive");
+ parseContext.ppError(directiveLoc, message.c_str(), "#include", "");
+ if (res) {
+ includer.releaseInclude(res);
+ }
+ }
+ }
+ }
+ return token;
+}
+
+// Handle #line
+int TPpContext::CPPline(TPpToken* ppToken)
+{
+ // "#line must have, after macro substitution, one of the following forms:
+ // "#line line
+ // "#line line source-string-number"
+
+ int token = scanToken(ppToken);
+ const TSourceLoc directiveLoc = ppToken->loc;
+ if (token == '\n') {
+ parseContext.ppError(ppToken->loc, "must by followed by an integral literal", "#line", "");
+ return token;
+ }
+
+ int lineRes = 0; // Line number after macro expansion.
+ int lineToken = 0;
+ bool hasFile = false;
+ int fileRes = 0; // Source file number after macro expansion.
+ const char* sourceName = nullptr; // Optional source file name.
+ bool lineErr = false;
+ bool fileErr = false;
+ token = eval(token, MIN_PRECEDENCE, false, lineRes, lineErr, ppToken);
+ if (! lineErr) {
+ lineToken = lineRes;
+ if (token == '\n')
+ ++lineRes;
+
+ if (parseContext.lineDirectiveShouldSetNextLine())
+ --lineRes;
+ parseContext.setCurrentLine(lineRes);
+
+ if (token != '\n') {
+ if (token == PpAtomConstString) {
+ parseContext.ppRequireExtensions(directiveLoc, 1, &E_GL_GOOGLE_cpp_style_line_directive, "filename-based #line");
+ // We need to save a copy of the string instead of pointing
+ // to the name field of the token since the name field
+ // will likely be overwritten by the next token scan.
+ sourceName = GetAtomString(LookUpAddString(ppToken->name));
+ parseContext.setCurrentSourceName(sourceName);
+ hasFile = true;
+ token = scanToken(ppToken);
+ } else {
+ token = eval(token, MIN_PRECEDENCE, false, fileRes, fileErr, ppToken);
+ if (! fileErr) {
+ parseContext.setCurrentString(fileRes);
+ hasFile = true;
+ }
+ }
+ }
+ }
+ if (!fileErr && !lineErr) {
+ parseContext.notifyLineDirective(directiveLoc.line, lineToken, hasFile, fileRes, sourceName);
+ }
+ token = extraTokenCheck(PpAtomLine, ppToken, token);
+
+ return token;
+}
+
+// Handle #error
+int TPpContext::CPPerror(TPpToken* ppToken)
+{
+ int token = scanToken(ppToken);
+ std::string message;
+ TSourceLoc loc = ppToken->loc;
+
+ while (token != '\n' && token != EndOfInput) {
+ if (token == PpAtomConstInt || token == PpAtomConstUint ||
+ token == PpAtomConstInt64 || token == PpAtomConstUint64 ||
+ token == PpAtomConstFloat || token == PpAtomConstDouble) {
+ message.append(ppToken->name);
+ } else if (token == PpAtomIdentifier || token == PpAtomConstString) {
+ message.append(ppToken->name);
+ } else {
+ message.append(GetAtomString(token));
+ }
+ message.append(" ");
+ token = scanToken(ppToken);
+ }
+ parseContext.notifyErrorDirective(loc.line, message.c_str());
+ //store this msg into the shader's information log..set the Compile Error flag!!!!
+ parseContext.ppError(loc, message.c_str(), "#error", "");
+
+ return '\n';
+}
+
+// Handle #pragma
+int TPpContext::CPPpragma(TPpToken* ppToken)
+{
+ char SrcStrName[2];
+ TVector<TString> tokens;
+
+ TSourceLoc loc = ppToken->loc; // because we go to the next line before processing
+ int token = scanToken(ppToken);
+ while (token != '\n' && token != EndOfInput) {
+ switch (token) {
+ case PpAtomIdentifier:
+ case PpAtomConstInt:
+ case PpAtomConstUint:
+ case PpAtomConstInt64:
+ case PpAtomConstUint64:
+ case PpAtomConstFloat:
+ case PpAtomConstDouble:
+ tokens.push_back(ppToken->name);
+ break;
+ default:
+ SrcStrName[0] = (char)token;
+ SrcStrName[1] = '\0';
+ tokens.push_back(SrcStrName);
+ }
+ token = scanToken(ppToken);
+ }
+
+ if (token == EndOfInput)
+ parseContext.ppError(loc, "directive must end with a newline", "#pragma", "");
+ else
+ parseContext.handlePragma(loc, tokens);
+
+ return token;
+}
+
+// #version: This is just for error checking: the version and profile are decided before preprocessing starts
+int TPpContext::CPPversion(TPpToken* ppToken)
+{
+ int token = scanToken(ppToken);
+
+ if (errorOnVersion || versionSeen)
+ parseContext.ppError(ppToken->loc, "must occur first in shader", "#version", "");
+ versionSeen = true;
+
+ if (token == '\n') {
+ parseContext.ppError(ppToken->loc, "must be followed by version number", "#version", "");
+
+ return token;
+ }
+
+ if (token != PpAtomConstInt)
+ parseContext.ppError(ppToken->loc, "must be followed by version number", "#version", "");
+
+ ppToken->ival = atoi(ppToken->name);
+ int versionNumber = ppToken->ival;
+ int line = ppToken->loc.line;
+ token = scanToken(ppToken);
+
+ if (token == '\n') {
+ parseContext.notifyVersion(line, versionNumber, nullptr);
+ return token;
+ } else {
+ if (ppToken->atom != PpAtomCore &&
+ ppToken->atom != PpAtomCompatibility &&
+ ppToken->atom != PpAtomEs)
+ parseContext.ppError(ppToken->loc, "bad profile name; use es, core, or compatibility", "#version", "");
+ parseContext.notifyVersion(line, versionNumber, ppToken->name);
+ token = scanToken(ppToken);
+
+ if (token == '\n')
+ return token;
+ else
+ parseContext.ppError(ppToken->loc, "bad tokens following profile -- expected newline", "#version", "");
+ }
+
+ return token;
+}
+
+// Handle #extension
+int TPpContext::CPPextension(TPpToken* ppToken)
+{
+ int line = ppToken->loc.line;
+ int token = scanToken(ppToken);
+ char extensionName[MaxTokenLength + 1];
+
+ if (token=='\n') {
+ parseContext.ppError(ppToken->loc, "extension name not specified", "#extension", "");
+ return token;
+ }
+
+ if (token != PpAtomIdentifier)
+ parseContext.ppError(ppToken->loc, "extension name expected", "#extension", "");
+
+ assert(strlen(ppToken->name) <= MaxTokenLength);
+ strcpy(extensionName, ppToken->name);
+
+ token = scanToken(ppToken);
+ if (token != ':') {
+ parseContext.ppError(ppToken->loc, "':' missing after extension name", "#extension", "");
+ return token;
+ }
+
+ token = scanToken(ppToken);
+ if (token != PpAtomIdentifier) {
+ parseContext.ppError(ppToken->loc, "behavior for extension not specified", "#extension", "");
+ return token;
+ }
+
+ parseContext.updateExtensionBehavior(line, extensionName, ppToken->name);
+ parseContext.notifyExtensionDirective(line, extensionName, ppToken->name);
+
+ token = scanToken(ppToken);
+ if (token == '\n')
+ return token;
+ else
+ parseContext.ppError(ppToken->loc, "extra tokens -- expected newline", "#extension","");
+
+ return token;
+}
+
+int TPpContext::readCPPline(TPpToken* ppToken)
+{
+ int token = scanToken(ppToken);
+
+ if (token == PpAtomIdentifier) {
+ switch (ppToken->atom) {
+ case PpAtomDefine:
+ token = CPPdefine(ppToken);
+ break;
+ case PpAtomElse:
+ if (elsetracker[elseSeen])
+ parseContext.ppError(ppToken->loc, "#else after #else", "#else", "");
+ elsetracker[elseSeen] = true;
+ if (! ifdepth)
+ parseContext.ppError(ppToken->loc, "mismatched statements", "#else", "");
+ token = extraTokenCheck(PpAtomElse, ppToken, scanToken(ppToken));
+ token = CPPelse(0, ppToken);
+ break;
+ case PpAtomElif:
+ if (! ifdepth)
+ parseContext.ppError(ppToken->loc, "mismatched statements", "#elif", "");
+ if (elseSeen[elsetracker])
+ parseContext.ppError(ppToken->loc, "#elif after #else", "#elif", "");
+ // this token is really a dont care, but we still need to eat the tokens
+ token = scanToken(ppToken);
+ while (token != '\n' && token != EndOfInput)
+ token = scanToken(ppToken);
+ token = CPPelse(0, ppToken);
+ break;
+ case PpAtomEndif:
+ if (! ifdepth)
+ parseContext.ppError(ppToken->loc, "mismatched statements", "#endif", "");
+ else {
+ elseSeen[elsetracker] = false;
+ --elsetracker;
+ --ifdepth;
+ }
+ token = extraTokenCheck(PpAtomEndif, ppToken, scanToken(ppToken));
+ break;
+ case PpAtomIf:
+ token = CPPif(ppToken);
+ break;
+ case PpAtomIfdef:
+ token = CPPifdef(1, ppToken);
+ break;
+ case PpAtomIfndef:
+ token = CPPifdef(0, ppToken);
+ break;
+ case PpAtomInclude:
+ parseContext.ppRequireExtensions(ppToken->loc, 1, &E_GL_GOOGLE_include_directive, "#include");
+ token = CPPinclude(ppToken);
+ break;
+ case PpAtomLine:
+ token = CPPline(ppToken);
+ break;
+ case PpAtomPragma:
+ token = CPPpragma(ppToken);
+ break;
+ case PpAtomUndef:
+ token = CPPundef(ppToken);
+ break;
+ case PpAtomError:
+ token = CPPerror(ppToken);
+ break;
+ case PpAtomVersion:
+ token = CPPversion(ppToken);
+ break;
+ case PpAtomExtension:
+ token = CPPextension(ppToken);
+ break;
+ default:
+ parseContext.ppError(ppToken->loc, "invalid directive:", "#", ppToken->name);
+ break;
+ }
+ } else if (token != '\n' && token != EndOfInput)
+ parseContext.ppError(ppToken->loc, "invalid directive", "#", "");
+
+ while (token != '\n' && token != EndOfInput)
+ token = scanToken(ppToken);
+
+ return token;
+}
+
+TPpContext::TokenStream* TPpContext::PrescanMacroArg(TokenStream* a, TPpToken* ppToken, bool newLineOkay)
+{
+ int token;
+ TokenStream *n;
+ RewindTokenStream(a);
+ do {
+ token = ReadToken(a, ppToken);
+ if (token == PpAtomIdentifier && LookUpSymbol(ppToken->atom))
+ break;
+ } while (token != EndOfInput);
+
+ if (token == EndOfInput)
+ return a;
+
+ n = new TokenStream;
+ pushInput(new tMarkerInput(this));
+ pushTokenStreamInput(a);
+ while ((token = scanToken(ppToken)) != tMarkerInput::marker) {
+ if (token == PpAtomIdentifier && MacroExpand(ppToken->atom, ppToken, false, newLineOkay) != 0)
+ continue;
+ RecordToken(n, token, ppToken);
+ }
+ popInput();
+ delete a;
+
+ return n;
+}
+
+//
+// Return the next token for a macro expansion, handling macro args.
+//
+int TPpContext::tMacroInput::scan(TPpToken* ppToken)
+{
+ int token;
+ do {
+ token = pp->ReadToken(mac->body, ppToken);
+ } while (token == ' '); // handle white space in macro
+
+ // TODO: preprocessor: properly handle whitespace (or lack of it) between tokens when expanding
+ if (token == PpAtomIdentifier) {
+ int i;
+ for (i = mac->argc - 1; i >= 0; i--)
+ if (mac->args[i] == ppToken->atom)
+ break;
+ if (i >= 0) {
+ pp->pushTokenStreamInput(args[i]);
+
+ return pp->scanToken(ppToken);
+ }
+ }
+
+ if (token == EndOfInput)
+ mac->busy = 0;
+
+ return token;
+}
+
+// return a textual zero, for scanning a macro that was never defined
+int TPpContext::tZeroInput::scan(TPpToken* ppToken)
+{
+ if (done)
+ return EndOfInput;
+
+ strcpy(ppToken->name, "0");
+ ppToken->ival = 0;
+ ppToken->space = false;
+ done = true;
+
+ return PpAtomConstInt;
+}
+
+//
+// Check an identifier (atom) to see if it is a macro that should be expanded.
+// If it is, and defined, push a tInput that will produce the appropriate expansion
+// and return 1.
+// If it is, but undefined, and expandUndef is requested, push a tInput that will
+// expand to 0 and return -1.
+// Otherwise, return 0 to indicate no expansion, which is not necessarily an error.
+//
+int TPpContext::MacroExpand(int atom, TPpToken* ppToken, bool expandUndef, bool newLineOkay)
+{
+ ppToken->space = false;
+ switch (atom) {
+ case PpAtomLineMacro:
+ ppToken->ival = parseContext.getCurrentLoc().line;
+ snprintf(ppToken->name, sizeof(ppToken->name), "%d", ppToken->ival);
+ UngetToken(PpAtomConstInt, ppToken);
+ return 1;
+
+ case PpAtomFileMacro: {
+ if (parseContext.getCurrentLoc().name)
+ parseContext.ppRequireExtensions(ppToken->loc, 1, &E_GL_GOOGLE_cpp_style_line_directive, "filename-based __FILE__");
+ ppToken->ival = parseContext.getCurrentLoc().string;
+ snprintf(ppToken->name, sizeof(ppToken->name), "%s", ppToken->loc.getStringNameOrNum().c_str());
+ UngetToken(PpAtomConstInt, ppToken);
+ return 1;
+ }
+
+ case PpAtomVersionMacro:
+ ppToken->ival = parseContext.version;
+ snprintf(ppToken->name, sizeof(ppToken->name), "%d", ppToken->ival);
+ UngetToken(PpAtomConstInt, ppToken);
+ return 1;
+
+ default:
+ break;
+ }
+
+ Symbol *sym = LookUpSymbol(atom);
+ int token;
+ int depth = 0;
+
+ // no recursive expansions
+ if (sym && sym->mac.busy)
+ return 0;
+
+ // not expanding undefined macros
+ if ((! sym || sym->mac.undef) && ! expandUndef)
+ return 0;
+
+ // 0 is the value of an undefined macro
+ if ((! sym || sym->mac.undef) && expandUndef) {
+ pushInput(new tZeroInput(this));
+ return -1;
+ }
+
+ tMacroInput *in = new tMacroInput(this);
+
+ TSourceLoc loc = ppToken->loc; // in case we go to the next line before discovering the error
+ in->mac = &sym->mac;
+ if (sym->mac.args) {
+ token = scanToken(ppToken);
+ if (newLineOkay) {
+ while (token == '\n')
+ token = scanToken(ppToken);
+ }
+ if (token != '(') {
+ parseContext.ppError(loc, "expected '(' following", "macro expansion", GetAtomString(atom));
+ UngetToken(token, ppToken);
+ ppToken->atom = atom;
+
+ delete in;
+ return 0;
+ }
+ in->args.resize(in->mac->argc);
+ for (int i = 0; i < in->mac->argc; i++)
+ in->args[i] = new TokenStream;
+ int arg = 0;
+ bool tokenRecorded = false;
+ do {
+ depth = 0;
+ while (1) {
+ token = scanToken(ppToken);
+ if (token == EndOfInput) {
+ parseContext.ppError(loc, "End of input in macro", "macro expansion", GetAtomString(atom));
+ delete in;
+ return 0;
+ }
+ if (token == '\n') {
+ if (! newLineOkay) {
+ parseContext.ppError(loc, "End of line in macro substitution:", "macro expansion", GetAtomString(atom));
+ delete in;
+ return 0;
+ }
+ continue;
+ }
+ if (token == '#') {
+ parseContext.ppError(ppToken->loc, "unexpected '#'", "macro expansion", GetAtomString(atom));
+ delete in;
+ return 0;
+ }
+ if (in->mac->argc == 0 && token != ')')
+ break;
+ if (depth == 0 && (token == ',' || token == ')'))
+ break;
+ if (token == '(')
+ depth++;
+ if (token == ')')
+ depth--;
+ RecordToken(in->args[arg], token, ppToken);
+ tokenRecorded = true;
+ }
+ if (token == ')') {
+ if (in->mac->argc == 1 && tokenRecorded == 0)
+ break;
+ arg++;
+ break;
+ }
+ arg++;
+ } while (arg < in->mac->argc);
+
+ if (arg < in->mac->argc)
+ parseContext.ppError(loc, "Too few args in Macro", "macro expansion", GetAtomString(atom));
+ else if (token != ')') {
+ depth=0;
+ while (token != EndOfInput && (depth > 0 || token != ')')) {
+ if (token == ')')
+ depth--;
+ token = scanToken(ppToken);
+ if (token == '(')
+ depth++;
+ }
+
+ if (token == EndOfInput) {
+ parseContext.ppError(loc, "End of input in macro", "macro expansion", GetAtomString(atom));
+ delete in;
+ return 0;
+ }
+ parseContext.ppError(loc, "Too many args in macro", "macro expansion", GetAtomString(atom));
+ }
+ for (int i = 0; i < in->mac->argc; i++)
+ in->args[i] = PrescanMacroArg(in->args[i], ppToken, newLineOkay);
+ }
+
+ pushInput(in);
+ sym->mac.busy = 1;
+ RewindTokenStream(sym->mac.body);
+
+ return 1;
+}
+
+} // end namespace glslang
diff --git a/chromium/third_party/glslang/src/glslang/MachineIndependent/preprocessor/PpAtom.cpp b/chromium/third_party/glslang/src/glslang/MachineIndependent/preprocessor/PpAtom.cpp
new file mode 100644
index 00000000000..763b6b4e67b
--- /dev/null
+++ b/chromium/third_party/glslang/src/glslang/MachineIndependent/preprocessor/PpAtom.cpp
@@ -0,0 +1,192 @@
+//
+//Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
+//Copyright (C) 2013 LunarG, Inc.
+//All rights reserved.
+//
+//Redistribution and use in source and binary forms, with or without
+//modification, are permitted provided that the following conditions
+//are met:
+//
+// Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+//
+// Neither the name of 3Dlabs Inc. Ltd. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+//"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+//LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+//FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+//COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+//INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+//BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+//LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+//CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+//LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+//ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+//POSSIBILITY OF SUCH DAMAGE.
+//
+/****************************************************************************\
+Copyright (c) 2002, NVIDIA Corporation.
+
+NVIDIA Corporation("NVIDIA") supplies this software to you in
+consideration of your agreement to the following terms, and your use,
+installation, modification or redistribution of this NVIDIA software
+constitutes acceptance of these terms. If you do not agree with these
+terms, please do not use, install, modify or redistribute this NVIDIA
+software.
+
+In consideration of your agreement to abide by the following terms, and
+subject to these terms, NVIDIA grants you a personal, non-exclusive
+license, under NVIDIA's copyrights in this original NVIDIA software (the
+"NVIDIA Software"), to use, reproduce, modify and redistribute the
+NVIDIA Software, with or without modifications, in source and/or binary
+forms; provided that if you redistribute the NVIDIA Software, you must
+retain the copyright notice of NVIDIA, this notice and the following
+text and disclaimers in all such redistributions of the NVIDIA Software.
+Neither the name, trademarks, service marks nor logos of NVIDIA
+Corporation may be used to endorse or promote products derived from the
+NVIDIA Software without specific prior written permission from NVIDIA.
+Except as expressly stated in this notice, no other rights or licenses
+express or implied, are granted by NVIDIA herein, including but not
+limited to any patent rights that may be infringed by your derivative
+works or by other works in which the NVIDIA Software may be
+incorporated. No hardware is licensed hereunder.
+
+THE NVIDIA SOFTWARE IS BEING PROVIDED ON AN "AS IS" BASIS, WITHOUT
+WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED,
+INCLUDING WITHOUT LIMITATION, WARRANTIES OR CONDITIONS OF TITLE,
+NON-INFRINGEMENT, MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR
+ITS USE AND OPERATION EITHER ALONE OR IN COMBINATION WITH OTHER
+PRODUCTS.
+
+IN NO EVENT SHALL NVIDIA BE LIABLE FOR ANY SPECIAL, INDIRECT,
+INCIDENTAL, EXEMPLARY, CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+TO, LOST PROFITS; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) OR ARISING IN ANY WAY
+OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION OF THE
+NVIDIA SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT,
+TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF
+NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+\****************************************************************************/
+
+//
+// atom.c
+//
+
+#define _CRT_SECURE_NO_WARNINGS
+
+#include <assert.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "PpContext.h"
+#include "PpTokens.h"
+
+namespace {
+
+using namespace glslang;
+
+const struct {
+ int val;
+ const char* str;
+} tokens[] = {
+ { PpAtomDefine, "define" },
+ { PpAtomDefined, "defined" },
+ { PpAtomUndef, "undef" },
+ { PpAtomIf, "if" },
+ { PpAtomElif, "elif" },
+ { PpAtomElse, "else" },
+ { PpAtomEndif, "endif" },
+ { PpAtomIfdef, "ifdef" },
+ { PpAtomIfndef, "ifndef" },
+ { PpAtomLine, "line" },
+ { PpAtomPragma, "pragma" },
+ { PpAtomError, "error" },
+
+ { PpAtomVersion, "version" },
+ { PpAtomCore, "core" },
+ { PpAtomCompatibility, "compatibility" },
+ { PpAtomEs, "es" },
+ { PpAtomExtension, "extension" },
+
+ { PpAtomLineMacro, "__LINE__" },
+ { PpAtomFileMacro, "__FILE__" },
+ { PpAtomVersionMacro, "__VERSION__" },
+
+ { PpAtomInclude, "include" },
+
+};
+
+} // end anonymous namespace
+
+namespace glslang {
+
+//
+// Map a new or existing string to an atom, inventing a new atom if necessary.
+//
+int TPpContext::LookUpAddString(const char* s)
+{
+ auto it = atomMap.find(s);
+ if (it == atomMap.end()) {
+ AddAtomFixed(s, nextAtom);
+ return nextAtom++;
+ } else
+ return it->second;
+}
+
+//
+// Map an already created atom to its string.
+//
+const char* TPpContext::GetAtomString(int atom)
+{
+ if ((size_t)atom >= stringMap.size())
+ return "<bad token>";
+
+ const TString* atomString = stringMap[atom];
+
+ return atomString ? atomString->c_str() : "<bad token>";
+}
+
+//
+// Add forced mapping of string to atom.
+//
+void TPpContext::AddAtomFixed(const char* s, int atom)
+{
+ auto it = atomMap.insert(std::pair<TString, int>(s, atom)).first;
+ if (stringMap.size() < (size_t)atom + 1)
+ stringMap.resize(atom + 100, 0);
+ stringMap[atom] = &it->first;
+}
+
+//
+// Initialize the atom table.
+//
+void TPpContext::InitAtomTable()
+{
+ // Add single character tokens to the atom table:
+ const char* s = "~!%^&*()-+=|,.<>/?;:[]{}#\\";
+ char t[2];
+
+ t[1] = '\0';
+ while (*s) {
+ t[0] = *s;
+ AddAtomFixed(t, s[0]);
+ s++;
+ }
+
+ // Add multiple character scanner tokens :
+ for (size_t ii = 0; ii < sizeof(tokens)/sizeof(tokens[0]); ii++)
+ AddAtomFixed(tokens[ii].str, tokens[ii].val);
+
+ nextAtom = PpAtomLast;
+}
+
+} // end namespace glslang
diff --git a/chromium/third_party/glslang/src/glslang/MachineIndependent/preprocessor/PpContext.cpp b/chromium/third_party/glslang/src/glslang/MachineIndependent/preprocessor/PpContext.cpp
new file mode 100644
index 00000000000..6f0b8a9a11a
--- /dev/null
+++ b/chromium/third_party/glslang/src/glslang/MachineIndependent/preprocessor/PpContext.cpp
@@ -0,0 +1,122 @@
+//
+//Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
+//Copyright (C) 2013 LunarG, Inc.
+//All rights reserved.
+//
+//Redistribution and use in source and binary forms, with or without
+//modification, are permitted provided that the following conditions
+//are met:
+//
+// Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+//
+// Neither the name of 3Dlabs Inc. Ltd. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+//"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+//LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+//FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+//COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+//INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+//BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+//LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+//CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+//LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+//ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+//POSSIBILITY OF SUCH DAMAGE.
+//
+/****************************************************************************\
+Copyright (c) 2002, NVIDIA Corporation.
+
+NVIDIA Corporation("NVIDIA") supplies this software to you in
+consideration of your agreement to the following terms, and your use,
+installation, modification or redistribution of this NVIDIA software
+constitutes acceptance of these terms. If you do not agree with these
+terms, please do not use, install, modify or redistribute this NVIDIA
+software.
+
+In consideration of your agreement to abide by the following terms, and
+subject to these terms, NVIDIA grants you a personal, non-exclusive
+license, under NVIDIA's copyrights in this original NVIDIA software (the
+"NVIDIA Software"), to use, reproduce, modify and redistribute the
+NVIDIA Software, with or without modifications, in source and/or binary
+forms; provided that if you redistribute the NVIDIA Software, you must
+retain the copyright notice of NVIDIA, this notice and the following
+text and disclaimers in all such redistributions of the NVIDIA Software.
+Neither the name, trademarks, service marks nor logos of NVIDIA
+Corporation may be used to endorse or promote products derived from the
+NVIDIA Software without specific prior written permission from NVIDIA.
+Except as expressly stated in this notice, no other rights or licenses
+express or implied, are granted by NVIDIA herein, including but not
+limited to any patent rights that may be infringed by your derivative
+works or by other works in which the NVIDIA Software may be
+incorporated. No hardware is licensed hereunder.
+
+THE NVIDIA SOFTWARE IS BEING PROVIDED ON AN "AS IS" BASIS, WITHOUT
+WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED,
+INCLUDING WITHOUT LIMITATION, WARRANTIES OR CONDITIONS OF TITLE,
+NON-INFRINGEMENT, MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR
+ITS USE AND OPERATION EITHER ALONE OR IN COMBINATION WITH OTHER
+PRODUCTS.
+
+IN NO EVENT SHALL NVIDIA BE LIABLE FOR ANY SPECIAL, INDIRECT,
+INCIDENTAL, EXEMPLARY, CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+TO, LOST PROFITS; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) OR ARISING IN ANY WAY
+OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION OF THE
+NVIDIA SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT,
+TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF
+NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+\****************************************************************************/
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "PpContext.h"
+
+namespace glslang {
+
+TPpContext::TPpContext(TParseContextBase& pc, const std::string& rootFileName, TShader::Includer& inclr) :
+ preamble(0), strings(0), parseContext(pc), includer(inclr), inComment(false),
+ rootFileName(rootFileName),
+ currentSourceFile(rootFileName)
+{
+ InitAtomTable();
+ InitScanner();
+
+ ifdepth = 0;
+ for (elsetracker = 0; elsetracker < maxIfNesting; elsetracker++)
+ elseSeen[elsetracker] = false;
+ elsetracker = 0;
+}
+
+TPpContext::~TPpContext()
+{
+ for (TSymbolMap::iterator it = symbols.begin(); it != symbols.end(); ++it)
+ delete it->second->mac.body;
+ mem_FreePool(pool);
+ delete [] preamble;
+
+ // free up the inputStack
+ while (! inputStack.empty())
+ popInput();
+}
+
+void TPpContext::setInput(TInputScanner& input, bool versionWillBeError)
+{
+ assert(inputStack.size() == 0);
+
+ pushInput(new tStringInput(this, input));
+
+ errorOnVersion = versionWillBeError;
+ versionSeen = false;
+}
+
+} // end namespace glslang
diff --git a/chromium/third_party/glslang/src/glslang/MachineIndependent/preprocessor/PpContext.h b/chromium/third_party/glslang/src/glslang/MachineIndependent/preprocessor/PpContext.h
new file mode 100644
index 00000000000..4e47fa055ec
--- /dev/null
+++ b/chromium/third_party/glslang/src/glslang/MachineIndependent/preprocessor/PpContext.h
@@ -0,0 +1,570 @@
+//
+//Copyright (C) 2013 LunarG, Inc.
+//All rights reserved.
+//
+//Redistribution and use in source and binary forms, with or without
+//modification, are permitted provided that the following conditions
+//are met:
+//
+// Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+//
+// Neither the name of 3Dlabs Inc. Ltd. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+//"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+//LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+//FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+//COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+//INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+//BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+//LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+//CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+//LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+//ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+//POSSIBILITY OF SUCH DAMAGE.
+//
+/****************************************************************************\
+Copyright (c) 2002, NVIDIA Corporation.
+
+NVIDIA Corporation("NVIDIA") supplies this software to you in
+consideration of your agreement to the following terms, and your use,
+installation, modification or redistribution of this NVIDIA software
+constitutes acceptance of these terms. If you do not agree with these
+terms, please do not use, install, modify or redistribute this NVIDIA
+software.
+
+In consideration of your agreement to abide by the following terms, and
+subject to these terms, NVIDIA grants you a personal, non-exclusive
+license, under NVIDIA's copyrights in this original NVIDIA software (the
+"NVIDIA Software"), to use, reproduce, modify and redistribute the
+NVIDIA Software, with or without modifications, in source and/or binary
+forms; provided that if you redistribute the NVIDIA Software, you must
+retain the copyright notice of NVIDIA, this notice and the following
+text and disclaimers in all such redistributions of the NVIDIA Software.
+Neither the name, trademarks, service marks nor logos of NVIDIA
+Corporation may be used to endorse or promote products derived from the
+NVIDIA Software without specific prior written permission from NVIDIA.
+Except as expressly stated in this notice, no other rights or licenses
+express or implied, are granted by NVIDIA herein, including but not
+limited to any patent rights that may be infringed by your derivative
+works or by other works in which the NVIDIA Software may be
+incorporated. No hardware is licensed hereunder.
+
+THE NVIDIA SOFTWARE IS BEING PROVIDED ON AN "AS IS" BASIS, WITHOUT
+WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED,
+INCLUDING WITHOUT LIMITATION, WARRANTIES OR CONDITIONS OF TITLE,
+NON-INFRINGEMENT, MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR
+ITS USE AND OPERATION EITHER ALONE OR IN COMBINATION WITH OTHER
+PRODUCTS.
+
+IN NO EVENT SHALL NVIDIA BE LIABLE FOR ANY SPECIAL, INDIRECT,
+INCIDENTAL, EXEMPLARY, CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+TO, LOST PROFITS; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) OR ARISING IN ANY WAY
+OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION OF THE
+NVIDIA SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT,
+TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF
+NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+\****************************************************************************/
+
+#ifndef PPCONTEXT_H
+#define PPCONTEXT_H
+
+#include <stack>
+#include <unordered_map>
+
+#include "../ParseHelper.h"
+
+/* windows only pragma */
+#ifdef _MSC_VER
+ #pragma warning(disable : 4127)
+#endif
+
+namespace glslang {
+
+class TPpToken {
+public:
+ TPpToken() : token(0), space(false), ival(0), dval(0.0), atom(0)
+ {
+ loc.init();
+ name[0] = 0;
+ }
+
+ bool operator==(const TPpToken& right)
+ {
+ return token == right.token && atom == right.atom &&
+ ival == right.ival && dval == right.dval &&
+ strcmp(name, right.name) == 0;
+ }
+ bool operator!=(const TPpToken& right) { return ! operator==(right); }
+
+ TSourceLoc loc;
+ int token;
+ bool space; // true if a space (for white space or a removed comment) should also be recognized, in front of the token returned
+ int ival;
+ double dval;
+ long long i64val;
+ int atom;
+ char name[MaxTokenLength + 1];
+};
+
+class TInputScanner;
+
+// This class is the result of turning a huge pile of C code communicating through globals
+// into a class. This was done to allowing instancing to attain thread safety.
+// Don't expect too much in terms of OO design.
+class TPpContext {
+public:
+ TPpContext(TParseContextBase&, const std::string& rootFileName, TShader::Includer&);
+ virtual ~TPpContext();
+
+ void setPreamble(const char* preamble, size_t length);
+
+ const char* tokenize(TPpToken* ppToken);
+
+ class tInput {
+ public:
+ tInput(TPpContext* p) : done(false), pp(p) { }
+ virtual ~tInput() { }
+
+ virtual int scan(TPpToken*) = 0;
+ virtual int getch() = 0;
+ virtual void ungetch() = 0;
+
+ // Will be called when we start reading tokens from this instance
+ virtual void notifyActivated() {}
+ // Will be called when we do not read tokens from this instance anymore
+ virtual void notifyDeleted() {}
+ protected:
+ bool done;
+ TPpContext* pp;
+ };
+
+ void setInput(TInputScanner& input, bool versionWillBeError);
+
+ void pushInput(tInput* in)
+ {
+ inputStack.push_back(in);
+ in->notifyActivated();
+ }
+ void popInput()
+ {
+ inputStack.back()->notifyDeleted();
+ delete inputStack.back();
+ inputStack.pop_back();
+ }
+
+ struct TokenStream {
+ TokenStream() : current(0) { }
+ TVector<unsigned char> data;
+ size_t current;
+ };
+
+ struct MemoryPool {
+ struct chunk *next;
+ uintptr_t free, end;
+ size_t chunksize;
+ uintptr_t alignmask;
+ };
+
+ //
+ // From Pp.cpp
+ //
+
+ struct MacroSymbol {
+ MacroSymbol() : argc(0), args(0), body(0), busy(0), undef(0) { }
+ int argc;
+ int *args;
+ TokenStream *body;
+ unsigned busy:1;
+ unsigned undef:1;
+ };
+
+ struct Symbol {
+ int atom;
+ MacroSymbol mac;
+ };
+
+ struct SymbolList {
+ struct SymbolList_Rec *next;
+ Symbol *symb;
+ };
+
+ MemoryPool *pool;
+ typedef TMap<int, Symbol*> TSymbolMap;
+ TSymbolMap symbols; // this has light use... just defined macros
+
+protected:
+ TPpContext(TPpContext&);
+ TPpContext& operator=(TPpContext&);
+
+ char* preamble; // string to parse, all before line 1 of string 0, it is 0 if no preamble
+ int preambleLength;
+ char** strings; // official strings of shader, starting a string 0 line 1
+ size_t* lengths;
+ int numStrings; // how many official strings there are
+ int currentString; // which string we're currently parsing (-1 for preamble)
+
+ // Scanner data:
+ int previous_token;
+ TParseContextBase& parseContext;
+
+ // Get the next token from *stack* of input sources, popping input sources
+ // that are out of tokens, down until an input sources is found that has a token.
+ // Return EndOfInput when there are no more tokens to be found by doing this.
+ int scanToken(TPpToken* ppToken)
+ {
+ int token = EndOfInput;
+
+ while (! inputStack.empty()) {
+ token = inputStack.back()->scan(ppToken);
+ if (token != EndOfInput)
+ break;
+ popInput();
+ }
+
+ return token;
+ }
+ int getChar() { return inputStack.back()->getch(); }
+ void ungetChar() { inputStack.back()->ungetch(); }
+
+ static const int maxMacroArgs = 64;
+ static const int maxIfNesting = 64;
+
+ int ifdepth; // current #if-#else-#endif nesting in the cpp.c file (pre-processor)
+ bool elseSeen[maxIfNesting]; // Keep a track of whether an else has been seen at a particular depth
+ int elsetracker; // #if-#else and #endif constructs...Counter.
+
+ class tMacroInput : public tInput {
+ public:
+ tMacroInput(TPpContext* pp) : tInput(pp) { }
+ virtual ~tMacroInput()
+ {
+ for (size_t i = 0; i < args.size(); ++i)
+ delete args[i];
+ }
+
+ virtual int scan(TPpToken*);
+ virtual int getch() { assert(0); return EndOfInput; }
+ virtual void ungetch() { assert(0); }
+ MacroSymbol *mac;
+ TVector<TokenStream*> args;
+ };
+
+ class tMarkerInput : public tInput {
+ public:
+ tMarkerInput(TPpContext* pp) : tInput(pp) { }
+ virtual int scan(TPpToken*)
+ {
+ if (done)
+ return EndOfInput;
+ done = true;
+
+ return marker;
+ }
+ virtual int getch() { assert(0); return EndOfInput; }
+ virtual void ungetch() { assert(0); }
+ static const int marker = -3;
+ };
+
+ class tZeroInput : public tInput {
+ public:
+ tZeroInput(TPpContext* pp) : tInput(pp) { }
+ virtual int scan(TPpToken*);
+ virtual int getch() { assert(0); return EndOfInput; }
+ virtual void ungetch() { assert(0); }
+ };
+
+ std::vector<tInput*> inputStack;
+ bool errorOnVersion;
+ bool versionSeen;
+
+ //
+ // from Pp.cpp
+ //
+
+ // Used to obtain #include content.
+ TShader::Includer& includer;
+
+ int InitCPP();
+ int CPPdefine(TPpToken * ppToken);
+ int CPPundef(TPpToken * ppToken);
+ int CPPelse(int matchelse, TPpToken * ppToken);
+ int extraTokenCheck(int atom, TPpToken* ppToken, int token);
+ int eval(int token, int precedence, bool shortCircuit, int& res, bool& err, TPpToken * ppToken);
+ int evalToToken(int token, bool shortCircuit, int& res, bool& err, TPpToken * ppToken);
+ int CPPif (TPpToken * ppToken);
+ int CPPifdef(int defined, TPpToken * ppToken);
+ int CPPinclude(TPpToken * ppToken);
+ int CPPline(TPpToken * ppToken);
+ int CPPerror(TPpToken * ppToken);
+ int CPPpragma(TPpToken * ppToken);
+ int CPPversion(TPpToken * ppToken);
+ int CPPextension(TPpToken * ppToken);
+ int readCPPline(TPpToken * ppToken);
+ TokenStream* PrescanMacroArg(TokenStream *a, TPpToken * ppToken, bool newLineOkay);
+ int MacroExpand(int atom, TPpToken* ppToken, bool expandUndef, bool newLineOkay);
+
+ //
+ // from PpSymbols.cpp
+ //
+ Symbol *NewSymbol(int name);
+ Symbol *AddSymbol(int atom);
+ Symbol *LookUpSymbol(int atom);
+
+ //
+ // From PpTokens.cpp
+ //
+ void lAddByte(TokenStream *fTok, unsigned char fVal);
+ int lReadByte(TokenStream *pTok);
+ void lUnreadByte(TokenStream *pTok);
+ void RecordToken(TokenStream* pTok, int token, TPpToken* ppToken);
+ void RewindTokenStream(TokenStream *pTok);
+ int ReadToken(TokenStream* pTok, TPpToken* ppToken);
+ void pushTokenStreamInput(TokenStream *ts);
+ void UngetToken(int token, TPpToken* ppToken);
+
+ class tTokenInput : public tInput {
+ public:
+ tTokenInput(TPpContext* pp, TokenStream* t) : tInput(pp), tokens(t) { }
+ virtual int scan(TPpToken *);
+ virtual int getch() { assert(0); return EndOfInput; }
+ virtual void ungetch() { assert(0); }
+ protected:
+ TokenStream *tokens;
+ };
+
+ class tUngotTokenInput : public tInput {
+ public:
+ tUngotTokenInput(TPpContext* pp, int t, TPpToken* p) : tInput(pp), token(t), lval(*p) { }
+ virtual int scan(TPpToken *);
+ virtual int getch() { assert(0); return EndOfInput; }
+ virtual void ungetch() { assert(0); }
+ protected:
+ int token;
+ TPpToken lval;
+ };
+
+ //
+ // From PpScanner.cpp
+ //
+ class tStringInput : public tInput {
+ public:
+ tStringInput(TPpContext* pp, TInputScanner& i) : tInput(pp), input(&i) { }
+ virtual int scan(TPpToken*);
+
+ // Scanner used to get source stream characters.
+ // - Escaped newlines are handled here, invisibly to the caller.
+ // - All forms of newline are handled, and turned into just a '\n'.
+ int getch()
+ {
+ int ch = input->get();
+
+ if (ch == '\\') {
+ // Move past escaped newlines, as many as sequentially exist
+ do {
+ if (input->peek() == '\r' || input->peek() == '\n') {
+ bool allowed = pp->parseContext.lineContinuationCheck(input->getSourceLoc(), pp->inComment);
+ if (! allowed && pp->inComment)
+ return '\\';
+
+ // escape one newline now
+ ch = input->get();
+ int nextch = input->get();
+ if (ch == '\r' && nextch == '\n')
+ ch = input->get();
+ else
+ ch = nextch;
+ } else
+ return '\\';
+ } while (ch == '\\');
+ }
+
+ // handle any non-escaped newline
+ if (ch == '\r' || ch == '\n') {
+ if (ch == '\r' && input->peek() == '\n')
+ input->get();
+ return '\n';
+ }
+
+ return ch;
+ }
+
+ // Scanner used to backup the source stream characters. Newlines are
+ // handled here, invisibly to the caller, meaning have to undo exactly
+ // what getch() above does (e.g., don't leave things in the middle of a
+ // sequence of escaped newlines).
+ void ungetch()
+ {
+ input->unget();
+
+ do {
+ int ch = input->peek();
+ if (ch == '\r' || ch == '\n') {
+ if (ch == '\n') {
+ // correct for two-character newline
+ input->unget();
+ if (input->peek() != '\r')
+ input->get();
+ }
+ // now in front of a complete newline, move past an escape character
+ input->unget();
+ if (input->peek() == '\\')
+ input->unget();
+ else {
+ input->get();
+ break;
+ }
+ } else
+ break;
+ } while (true);
+ }
+
+ protected:
+ TInputScanner* input;
+ };
+
+ // Holds a reference to included file data, as well as a
+ // prologue and an epilogue string. This can be scanned using the tInput
+ // interface and acts as a single source string.
+ class TokenizableIncludeFile : public tInput {
+ public:
+ // Copies prologue and epilogue. The includedFile must remain valid
+ // until this TokenizableIncludeFile is no longer used.
+ TokenizableIncludeFile(const TSourceLoc& startLoc,
+ const std::string& prologue,
+ TShader::Includer::IncludeResult* includedFile,
+ const std::string& epilogue,
+ TPpContext* pp)
+ : tInput(pp),
+ prologue_(prologue),
+ includedFile_(includedFile),
+ epilogue_(epilogue),
+ scanner(3, strings, lengths, names, 0, 0, true),
+ prevScanner(nullptr),
+ stringInput(pp, scanner)
+ {
+ strings[0] = prologue_.data();
+ strings[1] = includedFile_->file_data;
+ strings[2] = epilogue_.data();
+
+ lengths[0] = prologue_.size();
+ lengths[1] = includedFile_->file_length;
+ lengths[2] = epilogue_.size();
+
+ scanner.setLine(startLoc.line);
+ scanner.setString(startLoc.string);
+
+ scanner.setFile(startLoc.name, 0);
+ scanner.setFile(startLoc.name, 1);
+ scanner.setFile(startLoc.name, 2);
+ }
+
+ // tInput methods:
+ int scan(TPpToken* t) override { return stringInput.scan(t); }
+ int getch() override { return stringInput.getch(); }
+ void ungetch() override { stringInput.ungetch(); }
+
+ void notifyActivated() override
+ {
+ prevScanner = pp->parseContext.getScanner();
+ pp->parseContext.setScanner(&scanner);
+ pp->push_include(includedFile_);
+ }
+
+ void notifyDeleted() override
+ {
+ pp->parseContext.setScanner(prevScanner);
+ pp->pop_include();
+ }
+
+ private:
+ // Stores the prologue for this string.
+ const std::string prologue_;
+
+ // Stores the epilogue for this string.
+ const std::string epilogue_;
+
+ // Points to the IncludeResult that this TokenizableIncludeFile represents.
+ TShader::Includer::IncludeResult* includedFile_;
+
+ // Will point to prologue_, includedFile_->file_data and epilogue_
+ // This is passed to scanner constructor.
+ // These do not own the storage and it must remain valid until this
+ // object has been destroyed.
+ const char* strings[3];
+ // Length of str_, passed to scanner constructor.
+ size_t lengths[3];
+ // String names
+ const char* names[3];
+ // Scans over str_.
+ TInputScanner scanner;
+ // The previous effective scanner before the scanner in this instance
+ // has been activated.
+ TInputScanner* prevScanner;
+ // Delegate object implementing the tInput interface.
+ tStringInput stringInput;
+ };
+
+ int InitScanner();
+ int ScanFromString(char* s);
+ void missingEndifCheck();
+ int lFloatConst(int len, int ch, TPpToken* ppToken);
+
+ void push_include(TShader::Includer::IncludeResult* result)
+ {
+ currentSourceFile = result->file_name;
+ includeStack.push(result);
+ }
+
+ void pop_include()
+ {
+ TShader::Includer::IncludeResult* include = includeStack.top();
+ includeStack.pop();
+ includer.releaseInclude(include);
+ if (includeStack.empty()) {
+ currentSourceFile = rootFileName;
+ } else {
+ currentSourceFile = includeStack.top()->file_name;
+ }
+ }
+
+ bool inComment;
+
+ //
+ // From PpAtom.cpp
+ //
+ typedef TUnorderedMap<TString, int> TAtomMap;
+ typedef TVector<const TString*> TStringMap;
+
+ TAtomMap atomMap;
+ TStringMap stringMap;
+ std::stack<TShader::Includer::IncludeResult*> includeStack;
+ std::string currentSourceFile;
+ std::string rootFileName;
+ int nextAtom;
+ void InitAtomTable();
+ void AddAtomFixed(const char* s, int atom);
+ int LookUpAddString(const char* s);
+ const char* GetAtomString(int atom);
+
+ //
+ // From PpMemory.cpp
+ //
+ MemoryPool *mem_CreatePool(size_t chunksize, unsigned align);
+ void mem_FreePool(MemoryPool*);
+ void *mem_Alloc(MemoryPool* p, size_t size);
+ int mem_AddCleanup(MemoryPool* p, void (*fn)(void *, void*), void* arg1, void* arg2);
+};
+
+} // end namespace glslang
+
+#endif // PPCONTEXT_H
diff --git a/chromium/third_party/glslang/src/glslang/MachineIndependent/preprocessor/PpMemory.cpp b/chromium/third_party/glslang/src/glslang/MachineIndependent/preprocessor/PpMemory.cpp
new file mode 100644
index 00000000000..57a49fb893a
--- /dev/null
+++ b/chromium/third_party/glslang/src/glslang/MachineIndependent/preprocessor/PpMemory.cpp
@@ -0,0 +1,162 @@
+//
+//Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
+//Copyright (C) 2013 LunarG, Inc.
+//All rights reserved.
+//
+//Redistribution and use in source and binary forms, with or without
+//modification, are permitted provided that the following conditions
+//are met:
+//
+// Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+//
+// Neither the name of 3Dlabs Inc. Ltd. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+//"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+//LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+//FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+//COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+//INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+//BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+//LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+//CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+//LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+//ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+//POSSIBILITY OF SUCH DAMAGE.
+//
+/****************************************************************************\
+Copyright (c) 2002, NVIDIA Corporation.
+
+NVIDIA Corporation("NVIDIA") supplies this software to you in
+consideration of your agreement to the following terms, and your use,
+installation, modification or redistribution of this NVIDIA software
+constitutes acceptance of these terms. If you do not agree with these
+terms, please do not use, install, modify or redistribute this NVIDIA
+software.
+
+In consideration of your agreement to abide by the following terms, and
+subject to these terms, NVIDIA grants you a personal, non-exclusive
+license, under NVIDIA's copyrights in this original NVIDIA software (the
+"NVIDIA Software"), to use, reproduce, modify and redistribute the
+NVIDIA Software, with or without modifications, in source and/or binary
+forms; provided that if you redistribute the NVIDIA Software, you must
+retain the copyright notice of NVIDIA, this notice and the following
+text and disclaimers in all such redistributions of the NVIDIA Software.
+Neither the name, trademarks, service marks nor logos of NVIDIA
+Corporation may be used to endorse or promote products derived from the
+NVIDIA Software without specific prior written permission from NVIDIA.
+Except as expressly stated in this notice, no other rights or licenses
+express or implied, are granted by NVIDIA herein, including but not
+limited to any patent rights that may be infringed by your derivative
+works or by other works in which the NVIDIA Software may be
+incorporated. No hardware is licensed hereunder.
+
+THE NVIDIA SOFTWARE IS BEING PROVIDED ON AN "AS IS" BASIS, WITHOUT
+WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED,
+INCLUDING WITHOUT LIMITATION, WARRANTIES OR CONDITIONS OF TITLE,
+NON-INFRINGEMENT, MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR
+ITS USE AND OPERATION EITHER ALONE OR IN COMBINATION WITH OTHER
+PRODUCTS.
+
+IN NO EVENT SHALL NVIDIA BE LIABLE FOR ANY SPECIAL, INDIRECT,
+INCIDENTAL, EXEMPLARY, CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+TO, LOST PROFITS; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) OR ARISING IN ANY WAY
+OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION OF THE
+NVIDIA SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT,
+TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF
+NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+\****************************************************************************/
+
+#include <stddef.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdint.h>
+
+#include "PpContext.h"
+
+// default alignment and chunksize, if called with 0 arguments
+#define CHUNKSIZE (64*1024)
+#define ALIGN 8
+
+namespace glslang {
+
+struct chunk {
+ struct chunk *next;
+};
+
+TPpContext::MemoryPool* TPpContext::mem_CreatePool(size_t chunksize, unsigned int align)
+{
+ if (align == 0)
+ align = ALIGN;
+ if (chunksize == 0)
+ chunksize = CHUNKSIZE;
+ if (align & (align - 1))
+ return nullptr;
+ if (chunksize < sizeof(MemoryPool))
+ return nullptr;
+ if (chunksize & (align - 1))
+ return nullptr;
+
+ MemoryPool *pool = (MemoryPool*)malloc(chunksize);
+ if (! pool)
+ return nullptr;
+
+ pool->next = 0;
+ pool->chunksize = chunksize;
+ pool->alignmask = (uintptr_t)(align) - 1;
+ pool->free = ((uintptr_t)(pool + 1) + pool->alignmask) & ~pool->alignmask;
+ pool->end = (uintptr_t)pool + chunksize;
+
+ return pool;
+}
+
+void TPpContext::mem_FreePool(MemoryPool *pool)
+{
+ struct chunk *p, *next;
+
+ for (p = (struct chunk *)pool; p; p = next) {
+ next = p->next;
+ free(p);
+ }
+}
+
+void* TPpContext::mem_Alloc(MemoryPool *pool, size_t size)
+{
+ struct chunk *ch;
+ void *rv = (void *)pool->free;
+ size = (size + pool->alignmask) & ~pool->alignmask;
+ if (size <= 0) size = pool->alignmask;
+ pool->free += size;
+ if (pool->free > pool->end || pool->free < (uintptr_t)rv) {
+ size_t minreq = (size + sizeof(struct chunk) + pool->alignmask) & ~pool->alignmask;
+ pool->free = (uintptr_t)rv;
+ if (minreq >= pool->chunksize) {
+ // request size is too big for the chunksize, so allocate it as
+ // a single chunk of the right size
+ ch = (struct chunk*)malloc(minreq);
+ if (! ch)
+ return nullptr;
+ } else {
+ ch = (struct chunk*)malloc(pool->chunksize);
+ if (! ch)
+ return nullptr;
+ pool->free = (uintptr_t)ch + minreq;
+ pool->end = (uintptr_t)ch + pool->chunksize;
+ }
+ ch->next = pool->next;
+ pool->next = ch;
+ rv = (void *)(((uintptr_t)(ch+1) + pool->alignmask) & ~pool->alignmask);
+ }
+ return rv;
+}
+
+} // end namespace glslang
diff --git a/chromium/third_party/glslang/src/glslang/MachineIndependent/preprocessor/PpScanner.cpp b/chromium/third_party/glslang/src/glslang/MachineIndependent/preprocessor/PpScanner.cpp
new file mode 100644
index 00000000000..b3d1af6dad2
--- /dev/null
+++ b/chromium/third_party/glslang/src/glslang/MachineIndependent/preprocessor/PpScanner.cpp
@@ -0,0 +1,778 @@
+//
+//Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
+//Copyright (C) 2013 LunarG, Inc.
+//All rights reserved.
+//
+//Redistribution and use in source and binary forms, with or without
+//modification, are permitted provided that the following conditions
+//are met:
+//
+// Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+//
+// Neither the name of 3Dlabs Inc. Ltd. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+//"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+//LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+//FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+//COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+//INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+//BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+//LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+//CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+//LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+//ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+//POSSIBILITY OF SUCH DAMAGE.
+//
+/****************************************************************************\
+Copyright (c) 2002, NVIDIA Corporation.
+
+NVIDIA Corporation("NVIDIA") supplies this software to you in
+consideration of your agreement to the following terms, and your use,
+installation, modification or redistribution of this NVIDIA software
+constitutes acceptance of these terms. If you do not agree with these
+terms, please do not use, install, modify or redistribute this NVIDIA
+software.
+
+In consideration of your agreement to abide by the following terms, and
+subject to these terms, NVIDIA grants you a personal, non-exclusive
+license, under NVIDIA's copyrights in this original NVIDIA software (the
+"NVIDIA Software"), to use, reproduce, modify and redistribute the
+NVIDIA Software, with or without modifications, in source and/or binary
+forms; provided that if you redistribute the NVIDIA Software, you must
+retain the copyright notice of NVIDIA, this notice and the following
+text and disclaimers in all such redistributions of the NVIDIA Software.
+Neither the name, trademarks, service marks nor logos of NVIDIA
+Corporation may be used to endorse or promote products derived from the
+NVIDIA Software without specific prior written permission from NVIDIA.
+Except as expressly stated in this notice, no other rights or licenses
+express or implied, are granted by NVIDIA herein, including but not
+limited to any patent rights that may be infringed by your derivative
+works or by other works in which the NVIDIA Software may be
+incorporated. No hardware is licensed hereunder.
+
+THE NVIDIA SOFTWARE IS BEING PROVIDED ON AN "AS IS" BASIS, WITHOUT
+WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED,
+INCLUDING WITHOUT LIMITATION, WARRANTIES OR CONDITIONS OF TITLE,
+NON-INFRINGEMENT, MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR
+ITS USE AND OPERATION EITHER ALONE OR IN COMBINATION WITH OTHER
+PRODUCTS.
+
+IN NO EVENT SHALL NVIDIA BE LIABLE FOR ANY SPECIAL, INDIRECT,
+INCIDENTAL, EXEMPLARY, CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+TO, LOST PROFITS; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) OR ARISING IN ANY WAY
+OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION OF THE
+NVIDIA SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT,
+TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF
+NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+\****************************************************************************/
+//
+// scanner.c
+//
+
+#define _CRT_SECURE_NO_WARNINGS
+
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "PpContext.h"
+#include "PpTokens.h"
+#include "../Scan.h"
+
+namespace glslang {
+
+int TPpContext::InitScanner()
+{
+ // Add various atoms needed by the CPP line scanner:
+ if (!InitCPP())
+ return 0;
+
+ previous_token = '\n';
+
+ return 1;
+}
+
+///////////////////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////// Floating point constants: /////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////////////////////
+
+/*
+* lFloatConst() - Scan a single- or double-precision floating point constant. Assumes that the scanner
+* has seen at least one digit, followed by either a decimal '.' or the
+* letter 'e', or a precision ending (e.g., F or LF).
+*/
+
+int TPpContext::lFloatConst(int len, int ch, TPpToken* ppToken)
+{
+ bool HasDecimalOrExponent = false;
+ int declen;
+ int str_len;
+ int isDouble = 0;
+
+ declen = 0;
+
+ str_len=len;
+ char* str = ppToken->name;
+ if (ch == '.') {
+ HasDecimalOrExponent = true;
+ str[len++] = (char)ch;
+ ch = getChar();
+ while (ch >= '0' && ch <= '9') {
+ if (len < MaxTokenLength) {
+ declen++;
+ if (len > 0 || ch != '0') {
+ str[len] = (char)ch;
+ len++;
+ str_len++;
+ }
+ ch = getChar();
+ } else {
+ parseContext.ppError(ppToken->loc, "float literal too long", "", "");
+ len = 1;
+ str_len = 1;
+ }
+ }
+ }
+
+ // Exponent:
+
+ if (ch == 'e' || ch == 'E') {
+ HasDecimalOrExponent = true;
+ if (len >= MaxTokenLength) {
+ parseContext.ppError(ppToken->loc, "float literal too long", "", "");
+ len = 1;
+ str_len = 1;
+ } else {
+ str[len++] = (char)ch;
+ ch = getChar();
+ if (ch == '+') {
+ str[len++] = (char)ch;
+ ch = getChar();
+ } else if (ch == '-') {
+ str[len++] = (char)ch;
+ ch = getChar();
+ }
+ if (ch >= '0' && ch <= '9') {
+ while (ch >= '0' && ch <= '9') {
+ if (len < MaxTokenLength) {
+ str[len++] = (char)ch;
+ ch = getChar();
+ } else {
+ parseContext.ppError(ppToken->loc, "float literal too long", "", "");
+ len = 1;
+ str_len = 1;
+ }
+ }
+ } else {
+ parseContext.ppError(ppToken->loc, "bad character in float exponent", "", "");
+ }
+ }
+ }
+
+ if (len == 0) {
+ ppToken->dval = 0.0;
+ strcpy(str, "0.0");
+ } else {
+ if (ch == 'l' || ch == 'L') {
+ parseContext.doubleCheck(ppToken->loc, "double floating-point suffix");
+ if (! HasDecimalOrExponent)
+ parseContext.ppError(ppToken->loc, "float literal needs a decimal point or exponent", "", "");
+ int ch2 = getChar();
+ if (ch2 != 'f' && ch2 != 'F') {
+ ungetChar();
+ ungetChar();
+ } else {
+ if (len < MaxTokenLength) {
+ str[len++] = (char)ch;
+ str[len++] = (char)ch2;
+ isDouble = 1;
+ } else {
+ parseContext.ppError(ppToken->loc, "float literal too long", "", "");
+ len = 1,str_len=1;
+ }
+ }
+ } else if (ch == 'f' || ch == 'F') {
+ parseContext.profileRequires(ppToken->loc, EEsProfile, 300, nullptr, "floating-point suffix");
+ if (! parseContext.relaxedErrors())
+ parseContext.profileRequires(ppToken->loc, ~EEsProfile, 120, nullptr, "floating-point suffix");
+ if (! HasDecimalOrExponent)
+ parseContext.ppError(ppToken->loc, "float literal needs a decimal point or exponent", "", "");
+ if (len < MaxTokenLength)
+ str[len++] = (char)ch;
+ else {
+ parseContext.ppError(ppToken->loc, "float literal too long", "", "");
+ len = 1,str_len=1;
+ }
+ } else
+ ungetChar();
+
+ str[len]='\0';
+
+ ppToken->dval = strtod(str, nullptr);
+ }
+
+ if (isDouble)
+ return PpAtomConstDouble;
+ else
+ return PpAtomConstFloat;
+}
+
+//
+// Scanner used to tokenize source stream.
+//
+int TPpContext::tStringInput::scan(TPpToken* ppToken)
+{
+ char* tokenText = ppToken->name;
+ int AlreadyComplained = 0;
+ int len = 0;
+ int ch = 0;
+ int ii = 0;
+ unsigned long long ival = 0;
+ bool enableInt64 = pp->parseContext.version >= 450 && pp->parseContext.extensionTurnedOn(E_GL_ARB_gpu_shader_int64);
+
+ ppToken->ival = 0;
+ ppToken->i64val = 0;
+ ppToken->space = false;
+ ch = getch();
+ for (;;) {
+ while (ch == ' ' || ch == '\t') {
+ ppToken->space = true;
+ ch = getch();
+ }
+
+ ppToken->loc = pp->parseContext.getCurrentLoc();
+ len = 0;
+ switch (ch) {
+ default:
+ // Single character token, including EndOfInput, '#' and '\' (escaped newlines are handled at a lower level, so this is just a '\' token)
+ return ch;
+
+ case 'A': case 'B': case 'C': case 'D': case 'E':
+ case 'F': case 'G': case 'H': case 'I': case 'J':
+ case 'K': case 'L': case 'M': case 'N': case 'O':
+ case 'P': case 'Q': case 'R': case 'S': case 'T':
+ case 'U': case 'V': case 'W': case 'X': case 'Y':
+ case 'Z': case '_':
+ case 'a': case 'b': case 'c': case 'd': case 'e':
+ case 'f': case 'g': case 'h': case 'i': case 'j':
+ case 'k': case 'l': case 'm': case 'n': case 'o':
+ case 'p': case 'q': case 'r': case 's': case 't':
+ case 'u': case 'v': case 'w': case 'x': case 'y':
+ case 'z':
+ do {
+ if (len < MaxTokenLength) {
+ tokenText[len++] = (char)ch;
+ ch = getch();
+ } else {
+ if (! AlreadyComplained) {
+ pp->parseContext.ppError(ppToken->loc, "name too long", "", "");
+ AlreadyComplained = 1;
+ }
+ ch = getch();
+ }
+ } while ((ch >= 'a' && ch <= 'z') ||
+ (ch >= 'A' && ch <= 'Z') ||
+ (ch >= '0' && ch <= '9') ||
+ ch == '_');
+
+ // line continuation with no token before or after makes len == 0, and need to start over skipping white space, etc.
+ if (len == 0)
+ continue;
+
+ tokenText[len] = '\0';
+ ungetch();
+ ppToken->atom = pp->LookUpAddString(tokenText);
+ return PpAtomIdentifier;
+ case '0':
+ ppToken->name[len++] = (char)ch;
+ ch = getch();
+ if (ch == 'x' || ch == 'X') {
+ // must be hexidecimal
+
+ bool isUnsigned = false;
+ bool isInt64 = false;
+ ppToken->name[len++] = (char)ch;
+ ch = getch();
+ if ((ch >= '0' && ch <= '9') ||
+ (ch >= 'A' && ch <= 'F') ||
+ (ch >= 'a' && ch <= 'f')) {
+
+ ival = 0;
+ do {
+ if (ival <= 0x0fffffff || (enableInt64 && ival <= 0x0fffffffffffffffull)) {
+ ppToken->name[len++] = (char)ch;
+ if (ch >= '0' && ch <= '9') {
+ ii = ch - '0';
+ } else if (ch >= 'A' && ch <= 'F') {
+ ii = ch - 'A' + 10;
+ } else if (ch >= 'a' && ch <= 'f') {
+ ii = ch - 'a' + 10;
+ } else
+ pp->parseContext.ppError(ppToken->loc, "bad digit in hexidecimal literal", "", "");
+ ival = (ival << 4) | ii;
+ } else {
+ if (! AlreadyComplained) {
+ pp->parseContext.ppError(ppToken->loc, "hexidecimal literal too big", "", "");
+ AlreadyComplained = 1;
+ }
+ ival = 0xffffffffffffffffull;
+ }
+ ch = getch();
+ } while ((ch >= '0' && ch <= '9') ||
+ (ch >= 'A' && ch <= 'F') ||
+ (ch >= 'a' && ch <= 'f'));
+ } else {
+ pp->parseContext.ppError(ppToken->loc, "bad digit in hexidecimal literal", "", "");
+ }
+ if (ch == 'u' || ch == 'U') {
+ if (len < MaxTokenLength)
+ ppToken->name[len++] = (char)ch;
+ isUnsigned = true;
+
+ if (enableInt64) {
+ int nextCh = getch();
+ if ((ch == 'u' && nextCh == 'l') || (ch == 'U' && nextCh == 'L')) {
+ if (len < MaxTokenLength)
+ ppToken->name[len++] = (char)nextCh;
+ isInt64 = true;
+ } else
+ ungetch();
+ }
+ }
+ else if (enableInt64 && (ch == 'l' || ch == 'L')) {
+ if (len < MaxTokenLength)
+ ppToken->name[len++] = (char)ch;
+ isInt64 = true;
+ } else
+ ungetch();
+ ppToken->name[len] = '\0';
+
+ if (isInt64) {
+ ppToken->i64val = ival;
+ return isUnsigned ? PpAtomConstUint64 : PpAtomConstInt64;
+ } else {
+ ppToken->ival = (int)ival;
+ return isUnsigned ? PpAtomConstUint : PpAtomConstInt;
+ }
+ } else {
+ // could be octal integer or floating point, speculative pursue octal until it must be floating point
+
+ bool isUnsigned = false;
+ bool isInt64 = false;
+ bool octalOverflow = false;
+ bool nonOctal = false;
+ ival = 0;
+
+ // see how much octal-like stuff we can read
+ while (ch >= '0' && ch <= '7') {
+ if (len < MaxTokenLength)
+ ppToken->name[len++] = (char)ch;
+ else if (! AlreadyComplained) {
+ pp->parseContext.ppError(ppToken->loc, "numeric literal too long", "", "");
+ AlreadyComplained = 1;
+ }
+ if (ival <= 0x1fffffff || (enableInt64 && ival <= 0x1fffffffffffffffull)) {
+ ii = ch - '0';
+ ival = (ival << 3) | ii;
+ } else
+ octalOverflow = true;
+ ch = getch();
+ }
+
+ // could be part of a float...
+ if (ch == '8' || ch == '9') {
+ nonOctal = true;
+ do {
+ if (len < MaxTokenLength)
+ ppToken->name[len++] = (char)ch;
+ else if (! AlreadyComplained) {
+ pp->parseContext.ppError(ppToken->loc, "numeric literal too long", "", "");
+ AlreadyComplained = 1;
+ }
+ ch = getch();
+ } while (ch >= '0' && ch <= '9');
+ }
+ if (ch == '.' || ch == 'e' || ch == 'f' || ch == 'E' || ch == 'F')
+ return pp->lFloatConst(len, ch, ppToken);
+
+ // wasn't a float, so must be octal...
+ if (nonOctal)
+ pp->parseContext.ppError(ppToken->loc, "octal literal digit too large", "", "");
+
+ if (ch == 'u' || ch == 'U') {
+ if (len < MaxTokenLength)
+ ppToken->name[len++] = (char)ch;
+ isUnsigned = true;
+
+ if (enableInt64) {
+ int nextCh = getch();
+ if ((ch == 'u' && nextCh == 'l') || (ch == 'U' && nextCh == 'L')) {
+ if (len < MaxTokenLength)
+ ppToken->name[len++] = (char)nextCh;
+ isInt64 = true;
+ } else
+ ungetch();
+ }
+ }
+ else if (enableInt64 && (ch == 'l' || ch == 'L')) {
+ if (len < MaxTokenLength)
+ ppToken->name[len++] = (char)ch;
+ isInt64 = true;
+ } else
+ ungetch();
+ ppToken->name[len] = '\0';
+
+ if (octalOverflow)
+ pp->parseContext.ppError(ppToken->loc, "octal literal too big", "", "");
+
+ if (isInt64) {
+ ppToken->i64val = ival;
+ return isUnsigned ? PpAtomConstUint64 : PpAtomConstInt64;
+ } else {
+ ppToken->ival = (int)ival;
+ return isUnsigned ? PpAtomConstUint : PpAtomConstInt;
+ }
+ }
+ break;
+ case '1': case '2': case '3': case '4':
+ case '5': case '6': case '7': case '8': case '9':
+ // can't be hexidecimal or octal, is either decimal or floating point
+
+ do {
+ if (len < MaxTokenLength)
+ ppToken->name[len++] = (char)ch;
+ else if (! AlreadyComplained) {
+ pp->parseContext.ppError(ppToken->loc, "numeric literal too long", "", "");
+ AlreadyComplained = 1;
+ }
+ ch = getch();
+ } while (ch >= '0' && ch <= '9');
+ if (ch == '.' || ch == 'e' || ch == 'f' || ch == 'E' || ch == 'F') {
+ return pp->lFloatConst(len, ch, ppToken);
+ } else {
+ // Finish handling signed and unsigned integers
+ int numericLen = len;
+ bool isUnsigned = false;
+ bool isInt64 = false;
+ if (ch == 'u' || ch == 'U') {
+ if (len < MaxTokenLength)
+ ppToken->name[len++] = (char)ch;
+ isUnsigned = true;
+
+ if (enableInt64) {
+ int nextCh = getch();
+ if ((ch == 'u' && nextCh == 'l') || (ch == 'U' && nextCh == 'L')) {
+ if (len < MaxTokenLength)
+ ppToken->name[len++] = (char)nextCh;
+ isInt64 = true;
+ } else
+ ungetch();
+ }
+ } else if (enableInt64 && (ch == 'l' || ch == 'L')) {
+ if (len < MaxTokenLength)
+ ppToken->name[len++] = (char)ch;
+ isInt64 = true;
+ } else
+ ungetch();
+
+ ppToken->name[len] = '\0';
+ ival = 0;
+ const unsigned oneTenthMaxInt = 0xFFFFFFFFu / 10;
+ const unsigned remainderMaxInt = 0xFFFFFFFFu - 10 * oneTenthMaxInt;
+ const unsigned long long oneTenthMaxInt64 = 0xFFFFFFFFFFFFFFFFull / 10;
+ const unsigned long long remainderMaxInt64 = 0xFFFFFFFFFFFFFFFFull - 10 * oneTenthMaxInt64;
+ for (int i = 0; i < numericLen; i++) {
+ ch = ppToken->name[i] - '0';
+ if ((enableInt64 == false && ((ival > oneTenthMaxInt) || (ival == oneTenthMaxInt && (unsigned)ch > remainderMaxInt))) ||
+ (enableInt64 && ((ival > oneTenthMaxInt64) || (ival == oneTenthMaxInt64 && (unsigned long long)ch > remainderMaxInt64)))) {
+ pp->parseContext.ppError(ppToken->loc, "numeric literal too big", "", "");
+ ival = 0xFFFFFFFFFFFFFFFFull;
+ break;
+ } else
+ ival = ival * 10 + ch;
+ }
+
+ if (isInt64) {
+ ppToken->i64val = ival;
+ return isUnsigned ? PpAtomConstUint64 : PpAtomConstInt64;
+ } else {
+ ppToken->ival = (int)ival;
+ return isUnsigned ? PpAtomConstUint : PpAtomConstInt;
+ }
+ }
+ break;
+ case '-':
+ ch = getch();
+ if (ch == '-') {
+ return PpAtomDecrement;
+ } else if (ch == '=') {
+ return PpAtomSub;
+ } else {
+ ungetch();
+ return '-';
+ }
+ case '+':
+ ch = getch();
+ if (ch == '+') {
+ return PpAtomIncrement;
+ } else if (ch == '=') {
+ return PpAtomAdd;
+ } else {
+ ungetch();
+ return '+';
+ }
+ case '*':
+ ch = getch();
+ if (ch == '=') {
+ return PpAtomMul;
+ } else {
+ ungetch();
+ return '*';
+ }
+ case '%':
+ ch = getch();
+ if (ch == '=') {
+ return PpAtomMod;
+ } else {
+ ungetch();
+ return '%';
+ }
+ case '^':
+ ch = getch();
+ if (ch == '^') {
+ return PpAtomXor;
+ } else {
+ if (ch == '=')
+ return PpAtomXorAssign;
+ else{
+ ungetch();
+ return '^';
+ }
+ }
+
+ case '=':
+ ch = getch();
+ if (ch == '=') {
+ return PpAtomEQ;
+ } else {
+ ungetch();
+ return '=';
+ }
+ case '!':
+ ch = getch();
+ if (ch == '=') {
+ return PpAtomNE;
+ } else {
+ ungetch();
+ return '!';
+ }
+ case '|':
+ ch = getch();
+ if (ch == '|') {
+ return PpAtomOr;
+ } else if (ch == '=') {
+ return PpAtomOrAssign;
+ } else {
+ ungetch();
+ return '|';
+ }
+ case '&':
+ ch = getch();
+ if (ch == '&') {
+ return PpAtomAnd;
+ } else if (ch == '=') {
+ return PpAtomAndAssign;
+ } else {
+ ungetch();
+ return '&';
+ }
+ case '<':
+ ch = getch();
+ if (ch == '<') {
+ ch = getch();
+ if (ch == '=')
+ return PpAtomLeftAssign;
+ else {
+ ungetch();
+ return PpAtomLeft;
+ }
+ } else if (ch == '=') {
+ return PpAtomLE;
+ } else {
+ ungetch();
+ return '<';
+ }
+ case '>':
+ ch = getch();
+ if (ch == '>') {
+ ch = getch();
+ if (ch == '=')
+ return PpAtomRightAssign;
+ else {
+ ungetch();
+ return PpAtomRight;
+ }
+ } else if (ch == '=') {
+ return PpAtomGE;
+ } else {
+ ungetch();
+ return '>';
+ }
+ case '.':
+ ch = getch();
+ if (ch >= '0' && ch <= '9') {
+ ungetch();
+ return pp->lFloatConst(0, '.', ppToken);
+ } else {
+ ungetch();
+ return '.';
+ }
+ case '/':
+ ch = getch();
+ if (ch == '/') {
+ pp->inComment = true;
+ do {
+ ch = getch();
+ } while (ch != '\n' && ch != EndOfInput);
+ ppToken->space = true;
+ pp->inComment = false;
+
+ return ch;
+ } else if (ch == '*') {
+ ch = getch();
+ do {
+ while (ch != '*') {
+ if (ch == EndOfInput) {
+ pp->parseContext.ppError(ppToken->loc, "End of input in comment", "comment", "");
+ return ch;
+ }
+ ch = getch();
+ }
+ ch = getch();
+ if (ch == EndOfInput) {
+ pp->parseContext.ppError(ppToken->loc, "End of input in comment", "comment", "");
+ return ch;
+ }
+ } while (ch != '/');
+ ppToken->space = true;
+ // loop again to get the next token...
+ break;
+ } else if (ch == '=') {
+ return PpAtomDiv;
+ } else {
+ ungetch();
+ return '/';
+ }
+ break;
+ case '"':
+ ch = getch();
+ while (ch != '"' && ch != '\n' && ch != EndOfInput) {
+ if (len < MaxTokenLength) {
+ tokenText[len] = (char)ch;
+ len++;
+ ch = getch();
+ } else
+ break;
+ };
+ tokenText[len] = '\0';
+ if (ch != '"') {
+ ungetch();
+ pp->parseContext.ppError(ppToken->loc, "End of line in string", "string", "");
+ }
+ return PpAtomConstString;
+ }
+
+ ch = getch();
+ }
+}
+
+//
+// The main functional entry-point into the preprocessor, which will
+// scan the source strings to figure out and return the next processing token.
+//
+// Return string pointer to next token.
+// Return 0 when no more tokens.
+//
+const char* TPpContext::tokenize(TPpToken* ppToken)
+{
+ int token = '\n';
+
+ for(;;) {
+ token = scanToken(ppToken);
+ ppToken->token = token;
+ if (token == EndOfInput) {
+ missingEndifCheck();
+ return nullptr;
+ }
+ if (token == '#') {
+ if (previous_token == '\n') {
+ token = readCPPline(ppToken);
+ if (token == EndOfInput) {
+ missingEndifCheck();
+ return nullptr;
+ }
+ continue;
+ } else {
+ parseContext.ppError(ppToken->loc, "preprocessor directive cannot be preceded by another token", "#", "");
+ return nullptr;
+ }
+ }
+ previous_token = token;
+
+ if (token == '\n')
+ continue;
+
+ // expand macros
+ if (token == PpAtomIdentifier && MacroExpand(ppToken->atom, ppToken, false, true) != 0)
+ continue;
+
+ const char* tokenString = nullptr;
+ switch (token) {
+ case PpAtomIdentifier:
+ case PpAtomConstInt:
+ case PpAtomConstUint:
+ case PpAtomConstFloat:
+ case PpAtomConstInt64:
+ case PpAtomConstUint64:
+ case PpAtomConstDouble:
+ tokenString = ppToken->name;
+ break;
+ case PpAtomConstString:
+ parseContext.ppError(ppToken->loc, "string literals not supported", "\"\"", "");
+ break;
+ case '\'':
+ parseContext.ppError(ppToken->loc, "character literals not supported", "\'", "");
+ break;
+ default:
+ tokenString = GetAtomString(token);
+ break;
+ }
+
+ if (tokenString) {
+ if (tokenString[0] != 0)
+ parseContext.tokensBeforeEOF = 1;
+
+ return tokenString;
+ }
+ }
+}
+
+// Checks if we've seen balanced #if...#endif
+void TPpContext::missingEndifCheck()
+{
+ if (ifdepth > 0)
+ parseContext.ppError(parseContext.getCurrentLoc(), "missing #endif", "", "");
+}
+
+} // end namespace glslang
diff --git a/chromium/third_party/glslang/src/glslang/MachineIndependent/preprocessor/PpSymbols.cpp b/chromium/third_party/glslang/src/glslang/MachineIndependent/preprocessor/PpSymbols.cpp
new file mode 100644
index 00000000000..c2ab7c0a11e
--- /dev/null
+++ b/chromium/third_party/glslang/src/glslang/MachineIndependent/preprocessor/PpSymbols.cpp
@@ -0,0 +1,135 @@
+//
+//Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
+//Copyright (C) 2013 LunarG, Inc.
+//All rights reserved.
+//
+//Redistribution and use in source and binary forms, with or without
+//modification, are permitted provided that the following conditions
+//are met:
+//
+// Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+//
+// Neither the name of 3Dlabs Inc. Ltd. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+//"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+//LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+//FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+//COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+//INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+//BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+//LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+//CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+//LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+//ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+//POSSIBILITY OF SUCH DAMAGE.
+//
+/****************************************************************************\
+Copyright (c) 2002, NVIDIA Corporation.
+
+NVIDIA Corporation("NVIDIA") supplies this software to you in
+consideration of your agreement to the following terms, and your use,
+installation, modification or redistribution of this NVIDIA software
+constitutes acceptance of these terms. If you do not agree with these
+terms, please do not use, install, modify or redistribute this NVIDIA
+software.
+
+In consideration of your agreement to abide by the following terms, and
+subject to these terms, NVIDIA grants you a personal, non-exclusive
+license, under NVIDIA's copyrights in this original NVIDIA software (the
+"NVIDIA Software"), to use, reproduce, modify and redistribute the
+NVIDIA Software, with or without modifications, in source and/or binary
+forms; provided that if you redistribute the NVIDIA Software, you must
+retain the copyright notice of NVIDIA, this notice and the following
+text and disclaimers in all such redistributions of the NVIDIA Software.
+Neither the name, trademarks, service marks nor logos of NVIDIA
+Corporation may be used to endorse or promote products derived from the
+NVIDIA Software without specific prior written permission from NVIDIA.
+Except as expressly stated in this notice, no other rights or licenses
+express or implied, are granted by NVIDIA herein, including but not
+limited to any patent rights that may be infringed by your derivative
+works or by other works in which the NVIDIA Software may be
+incorporated. No hardware is licensed hereunder.
+
+THE NVIDIA SOFTWARE IS BEING PROVIDED ON AN "AS IS" BASIS, WITHOUT
+WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED,
+INCLUDING WITHOUT LIMITATION, WARRANTIES OR CONDITIONS OF TITLE,
+NON-INFRINGEMENT, MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR
+ITS USE AND OPERATION EITHER ALONE OR IN COMBINATION WITH OTHER
+PRODUCTS.
+
+IN NO EVENT SHALL NVIDIA BE LIABLE FOR ANY SPECIAL, INDIRECT,
+INCIDENTAL, EXEMPLARY, CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+TO, LOST PROFITS; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) OR ARISING IN ANY WAY
+OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION OF THE
+NVIDIA SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT,
+TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF
+NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+\****************************************************************************/
+//
+// symbols.c
+//
+
+#include <assert.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "PpContext.h"
+
+///////////////////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////// Symbol Table Variables: ///////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////////////////////
+
+namespace glslang {
+
+/*
+* Allocate a new symbol node;
+*
+*/
+TPpContext::Symbol* TPpContext::NewSymbol(int atom)
+{
+ Symbol* lSymb;
+ char* pch;
+ size_t ii;
+
+ lSymb = (Symbol *) mem_Alloc(pool, sizeof(Symbol));
+ lSymb->atom = atom;
+
+ // Clear macro
+ pch = (char*) &lSymb->mac;
+ for (ii = 0; ii < sizeof(lSymb->mac); ii++)
+ *pch++ = 0;
+
+ return lSymb;
+}
+
+TPpContext::Symbol* TPpContext::AddSymbol(int atom)
+{
+ Symbol *lSymb;
+
+ lSymb = NewSymbol(atom);
+ symbols[lSymb->atom] = lSymb;
+
+ return lSymb;
+}
+
+TPpContext::Symbol* TPpContext::LookUpSymbol(int atom)
+{
+ TSymbolMap::iterator it = symbols.find(atom);
+ if (it == symbols.end())
+ return nullptr;
+ else
+ return it->second;
+}
+
+} // end namespace glslang
diff --git a/chromium/third_party/glslang/src/glslang/MachineIndependent/preprocessor/PpTokens.cpp b/chromium/third_party/glslang/src/glslang/MachineIndependent/preprocessor/PpTokens.cpp
new file mode 100644
index 00000000000..54d495e11f2
--- /dev/null
+++ b/chromium/third_party/glslang/src/glslang/MachineIndependent/preprocessor/PpTokens.cpp
@@ -0,0 +1,278 @@
+//
+//Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
+//Copyright (C) 2013 LunarG, Inc.
+//All rights reserved.
+//
+//Redistribution and use in source and binary forms, with or without
+//modification, are permitted provided that the following conditions
+//are met:
+//
+// Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+//
+// Neither the name of 3Dlabs Inc. Ltd. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+//"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+//LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+//FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+//COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+//INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+//BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+//LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+//CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+//LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+//ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+//POSSIBILITY OF SUCH DAMAGE.
+//
+/****************************************************************************\
+Copyright (c) 2002, NVIDIA Corporation.
+
+NVIDIA Corporation("NVIDIA") supplies this software to you in
+consideration of your agreement to the following terms, and your use,
+installation, modification or redistribution of this NVIDIA software
+constitutes acceptance of these terms. If you do not agree with these
+terms, please do not use, install, modify or redistribute this NVIDIA
+software.
+
+In consideration of your agreement to abide by the following terms, and
+subject to these terms, NVIDIA grants you a personal, non-exclusive
+license, under NVIDIA's copyrights in this original NVIDIA software (the
+"NVIDIA Software"), to use, reproduce, modify and redistribute the
+NVIDIA Software, with or without modifications, in source and/or binary
+forms; provided that if you redistribute the NVIDIA Software, you must
+retain the copyright notice of NVIDIA, this notice and the following
+text and disclaimers in all such redistributions of the NVIDIA Software.
+Neither the name, trademarks, service marks nor logos of NVIDIA
+Corporation may be used to endorse or promote products derived from the
+NVIDIA Software without specific prior written permission from NVIDIA.
+Except as expressly stated in this notice, no other rights or licenses
+express or implied, are granted by NVIDIA herein, including but not
+limited to any patent rights that may be infringed by your derivative
+works or by other works in which the NVIDIA Software may be
+incorporated. No hardware is licensed hereunder.
+
+THE NVIDIA SOFTWARE IS BEING PROVIDED ON AN "AS IS" BASIS, WITHOUT
+WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED,
+INCLUDING WITHOUT LIMITATION, WARRANTIES OR CONDITIONS OF TITLE,
+NON-INFRINGEMENT, MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR
+ITS USE AND OPERATION EITHER ALONE OR IN COMBINATION WITH OTHER
+PRODUCTS.
+
+IN NO EVENT SHALL NVIDIA BE LIABLE FOR ANY SPECIAL, INDIRECT,
+INCIDENTAL, EXEMPLARY, CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+TO, LOST PROFITS; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) OR ARISING IN ANY WAY
+OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION OF THE
+NVIDIA SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT,
+TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF
+NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+\****************************************************************************/
+
+//
+// For recording and playing back the stream of tokens in a macro definition.
+//
+
+#if (defined(_MSC_VER) && _MSC_VER < 1900 /*vs2015*/)
+#define _CRT_SECURE_NO_WARNINGS
+#define snprintf sprintf_s
+#endif
+
+#include <assert.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+
+#include "PpContext.h"
+#include "PpTokens.h"
+
+namespace glslang {
+
+void TPpContext::lAddByte(TokenStream *fTok, unsigned char fVal)
+{
+ fTok->data.push_back(fVal);
+}
+
+/*
+* Get the next byte from a stream.
+*/
+int TPpContext::lReadByte(TokenStream *pTok)
+{
+ if (pTok->current < pTok->data.size())
+ return pTok->data[pTok->current++];
+ else
+ return EndOfInput;
+}
+
+void TPpContext::lUnreadByte(TokenStream *pTok)
+{
+ if (pTok->current > 0)
+ --pTok->current;
+}
+
+/*
+* Add a token to the end of a list for later playback.
+*/
+void TPpContext::RecordToken(TokenStream *pTok, int token, TPpToken* ppToken)
+{
+ const char* s;
+ char* str = NULL;
+
+ if (token > PpAtomMaxSingle)
+ lAddByte(pTok, (unsigned char)((token & 0x7f) + 0x80));
+ else
+ lAddByte(pTok, (unsigned char)(token & 0x7f));
+
+ switch (token) {
+ case PpAtomIdentifier:
+ case PpAtomConstString:
+ s = ppToken->name;
+ while (*s)
+ lAddByte(pTok, (unsigned char) *s++);
+ lAddByte(pTok, 0);
+ break;
+ case PpAtomConstInt:
+ case PpAtomConstUint:
+ case PpAtomConstInt64:
+ case PpAtomConstUint64:
+ case PpAtomConstFloat:
+ case PpAtomConstDouble:
+ str = ppToken->name;
+ while (*str) {
+ lAddByte(pTok, (unsigned char) *str);
+ str++;
+ }
+ lAddByte(pTok, 0);
+ break;
+ default:
+ break;
+ }
+}
+
+/*
+* Reset a token stream in preperation for reading.
+*/
+void TPpContext::RewindTokenStream(TokenStream *pTok)
+{
+ pTok->current = 0;
+}
+
+/*
+* Read the next token from a token stream (not the source stream, but stream used to hold a tokenized macro).
+*/
+int TPpContext::ReadToken(TokenStream *pTok, TPpToken *ppToken)
+{
+ char* tokenText = ppToken->name;
+ int ltoken, len;
+ int ch;
+
+ ltoken = lReadByte(pTok);
+ ppToken->loc = parseContext.getCurrentLoc();
+ if (ltoken > 127)
+ ltoken += 128;
+ switch (ltoken) {
+ case '#':
+ if (lReadByte(pTok) == '#') {
+ parseContext.requireProfile(ppToken->loc, ~EEsProfile, "token pasting (##)");
+ parseContext.profileRequires(ppToken->loc, ~EEsProfile, 130, 0, "token pasting (##)");
+ parseContext.error(ppToken->loc, "token pasting not implemented (internal error)", "##", "");
+ //return PpAtomPaste;
+ return ReadToken(pTok, ppToken);
+ } else
+ lUnreadByte(pTok);
+ break;
+ case PpAtomConstString:
+ case PpAtomIdentifier:
+ case PpAtomConstFloat:
+ case PpAtomConstDouble:
+ case PpAtomConstInt:
+ case PpAtomConstUint:
+ case PpAtomConstInt64:
+ case PpAtomConstUint64:
+ len = 0;
+ ch = lReadByte(pTok);
+ while (ch != 0 && ch != EndOfInput) {
+ if (len < MaxTokenLength) {
+ tokenText[len] = (char)ch;
+ len++;
+ ch = lReadByte(pTok);
+ } else {
+ parseContext.error(ppToken->loc, "token too long", "", "");
+ break;
+ }
+ }
+ tokenText[len] = 0;
+
+ switch (ltoken) {
+ case PpAtomIdentifier:
+ ppToken->atom = LookUpAddString(tokenText);
+ break;
+ case PpAtomConstString:
+ break;
+ case PpAtomConstFloat:
+ case PpAtomConstDouble:
+ ppToken->dval = atof(ppToken->name);
+ break;
+ case PpAtomConstInt:
+ case PpAtomConstUint:
+ if (len > 0 && tokenText[0] == '0') {
+ if (len > 1 && (tokenText[1] == 'x' || tokenText[1] == 'X'))
+ ppToken->ival = strtol(ppToken->name, 0, 16);
+ else
+ ppToken->ival = strtol(ppToken->name, 0, 8);
+ } else
+ ppToken->ival = atoi(ppToken->name);
+ break;
+ case PpAtomConstInt64:
+ case PpAtomConstUint64:
+ if (len > 0 && tokenText[0] == '0') {
+ if (len > 1 && (tokenText[1] == 'x' || tokenText[1] == 'X'))
+ ppToken->i64val = strtoll(ppToken->name, nullptr, 16);
+ else
+ ppToken->i64val = strtoll(ppToken->name, nullptr, 8);
+ } else
+ ppToken->i64val = atoll(ppToken->name);
+ break;
+ }
+ }
+
+ return ltoken;
+}
+
+int TPpContext::tTokenInput::scan(TPpToken* ppToken)
+{
+ return pp->ReadToken(tokens, ppToken);
+}
+
+void TPpContext::pushTokenStreamInput(TokenStream* ts)
+{
+ pushInput(new tTokenInput(this, ts));
+ RewindTokenStream(ts);
+}
+
+int TPpContext::tUngotTokenInput::scan(TPpToken* ppToken)
+{
+ if (done)
+ return EndOfInput;
+
+ int ret = token;
+ *ppToken = lval;
+ done = true;
+
+ return ret;
+}
+
+void TPpContext::UngetToken(int token, TPpToken* ppToken)
+{
+ pushInput(new tUngotTokenInput(this, token, ppToken));
+}
+
+} // end namespace glslang
diff --git a/chromium/third_party/glslang/src/glslang/MachineIndependent/preprocessor/PpTokens.h b/chromium/third_party/glslang/src/glslang/MachineIndependent/preprocessor/PpTokens.h
new file mode 100644
index 00000000000..87f0eb1a60a
--- /dev/null
+++ b/chromium/third_party/glslang/src/glslang/MachineIndependent/preprocessor/PpTokens.h
@@ -0,0 +1,171 @@
+//
+//Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
+//All rights reserved.
+//
+//Redistribution and use in source and binary forms, with or without
+//modification, are permitted provided that the following conditions
+//are met:
+//
+// Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+//
+// Neither the name of 3Dlabs Inc. Ltd. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+//"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+//LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+//FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+//COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+//INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+//BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+//LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+//CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+//LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+//ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+//POSSIBILITY OF SUCH DAMAGE.
+//
+/****************************************************************************\
+Copyright (c) 2002, NVIDIA Corporation.
+
+NVIDIA Corporation("NVIDIA") supplies this software to you in
+consideration of your agreement to the following terms, and your use,
+installation, modification or redistribution of this NVIDIA software
+constitutes acceptance of these terms. If you do not agree with these
+terms, please do not use, install, modify or redistribute this NVIDIA
+software.
+
+In consideration of your agreement to abide by the following terms, and
+subject to these terms, NVIDIA grants you a personal, non-exclusive
+license, under NVIDIA's copyrights in this original NVIDIA software (the
+"NVIDIA Software"), to use, reproduce, modify and redistribute the
+NVIDIA Software, with or without modifications, in source and/or binary
+forms; provided that if you redistribute the NVIDIA Software, you must
+retain the copyright notice of NVIDIA, this notice and the following
+text and disclaimers in all such redistributions of the NVIDIA Software.
+Neither the name, trademarks, service marks nor logos of NVIDIA
+Corporation may be used to endorse or promote products derived from the
+NVIDIA Software without specific prior written permission from NVIDIA.
+Except as expressly stated in this notice, no other rights or licenses
+express or implied, are granted by NVIDIA herein, including but not
+limited to any patent rights that may be infringed by your derivative
+works or by other works in which the NVIDIA Software may be
+incorporated. No hardware is licensed hereunder.
+
+THE NVIDIA SOFTWARE IS BEING PROVIDED ON AN "AS IS" BASIS, WITHOUT
+WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED,
+INCLUDING WITHOUT LIMITATION, WARRANTIES OR CONDITIONS OF TITLE,
+NON-INFRINGEMENT, MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR
+ITS USE AND OPERATION EITHER ALONE OR IN COMBINATION WITH OTHER
+PRODUCTS.
+
+IN NO EVENT SHALL NVIDIA BE LIABLE FOR ANY SPECIAL, INDIRECT,
+INCIDENTAL, EXEMPLARY, CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+TO, LOST PROFITS; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) OR ARISING IN ANY WAY
+OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION OF THE
+NVIDIA SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT,
+TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF
+NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+\****************************************************************************/
+
+#ifndef PARSER_H
+#define PARSER_H
+
+namespace glslang {
+
+// Multi-character tokens
+enum EFixedAtoms {
+ PpAtomMaxSingle = 256, // single character tokens get their own char value as their token, skip them
+
+ // Operators
+
+ PpAtomAdd,
+ PpAtomSub,
+ PpAtomMul,
+ PpAtomDiv,
+ PpAtomMod,
+
+ PpAtomRight,
+ PpAtomLeft,
+
+ PpAtomRightAssign,
+ PpAtomLeftAssign,
+ PpAtomAndAssign,
+ PpAtomOrAssign,
+ PpAtomXorAssign,
+
+ PpAtomAnd,
+ PpAtomOr,
+ PpAtomXor,
+
+ PpAtomEQ,
+ PpAtomNE,
+ PpAtomGE,
+ PpAtomLE,
+
+ PpAtomDecrement,
+ PpAtomIncrement,
+
+ PpAtomPaste,
+
+ // Constants
+
+ PpAtomConstInt,
+ PpAtomConstUint,
+ PpAtomConstInt64,
+ PpAtomConstUint64,
+ PpAtomConstFloat,
+ PpAtomConstDouble,
+ PpAtomConstString,
+
+ // Indentifiers
+ PpAtomIdentifier,
+
+ // preprocessor "keywords"
+
+ PpAtomDefine,
+ PpAtomDefined,
+ PpAtomUndef,
+
+ PpAtomIf,
+ PpAtomIfdef,
+ PpAtomIfndef,
+ PpAtomElse,
+ PpAtomElif,
+ PpAtomEndif,
+
+ PpAtomLine,
+ PpAtomPragma,
+ PpAtomError,
+
+ // #version ...
+ PpAtomVersion,
+ PpAtomCore,
+ PpAtomCompatibility,
+ PpAtomEs,
+
+ // #extension
+ PpAtomExtension,
+
+ // __LINE__, __FILE__, __VERSION__
+
+ PpAtomLineMacro,
+ PpAtomFileMacro,
+ PpAtomVersionMacro,
+
+ // #include
+ PpAtomInclude,
+
+ PpAtomLast,
+};
+
+} // end namespace glslang
+
+#endif /* not PARSER_H */