//
// Copyright (C) 2002-2005  3Dlabs Inc. Ltd.
// Copyright (C) 2013 LunarG, Inc.
// Copyright (C) 2015-2018 Google, 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 _CRT_SECURE_NO_WARNINGS
#define _CRT_SECURE_NO_WARNINGS
#endif

#include <sstream>
#include <cstdlib>
#include <cstring>
#include <cctype>
#include <climits>

#include "PpContext.h"
#include "PpTokens.h"

namespace glslang {

// Handle #define
int TPpContext::CPPdefine(TPpToken* ppToken)
{
    MacroSymbol mac;

    // get the 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 macro name
    const int defAtom = atomStrings.getAddAtom(ppToken->name);
    TSourceLoc defineLoc = ppToken->loc; // because ppToken might go to the next line before we report errors

    // gather parameters to the macro, between (...)
    token = scanToken(ppToken);
    if (token == '(' && !ppToken->space) {
        mac.functionLike = 1;
        do {
            token = scanToken(ppToken);
            if (mac.args.size() == 0 && token == ')')
                break;
            if (token != PpAtomIdentifier) {
                parseContext.ppError(ppToken->loc, "bad argument", "#define", "");

                return token;
            }
            const int argAtom = atomStrings.getAddAtom(ppToken->name);

            // check for duplication of parameter name
            bool duplicate = false;
            for (size_t a = 0; a < mac.args.size(); ++a) {
                if (mac.args[a] == argAtom) {
                    parseContext.ppError(ppToken->loc, "duplicate macro parameter", "#define", "");
                    duplicate = true;
                    break;
                }
            }
            if (! duplicate)
                mac.args.push_back(argAtom);
            token = scanToken(ppToken);
        } while (token == ',');
        if (token != ')') {
            parseContext.ppError(ppToken->loc, "missing parenthesis", "#define", "");

            return token;
        }

        token = scanToken(ppToken);
    } else if (token != '\n' && token != EndOfInput && !ppToken->space) {
        parseContext.ppWarn(ppToken->loc, "missing space after macro name", "#define", "");

        return token;
    }

    // record the definition of the macro
    while (token != '\n' && token != EndOfInput) {
        mac.body.putToken(token, ppToken);
        token = scanToken(ppToken);
        if (token != '\n' && ppToken->space)
            mac.body.putToken(' ', ppToken);
    }

    // check for duplicate definition
    MacroSymbol* existing = lookupMacroDef(defAtom);
    if (existing != nullptr) {
        if (! existing->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 (existing->functionLike != mac.functionLike) {
                parseContext.ppError(defineLoc, "Macro redefined; function-like versus object-like:", "#define",
                    atomStrings.getString(defAtom));
            } else if (existing->args.size() != mac.args.size()) {
                parseContext.ppError(defineLoc, "Macro redefined; different number of arguments:", "#define",
                    atomStrings.getString(defAtom));
            } else {
                if (existing->args != mac.args) {
                    parseContext.ppError(defineLoc, "Macro redefined; different argument names:", "#define",
                       atomStrings.getString(defAtom));
                }
                // set up to compare the two
                existing->body.reset();
                mac.body.reset();
                int newToken;
                bool firstToken = true;
                do {
                    int oldToken;
                    TPpToken oldPpToken;
                    TPpToken newPpToken;
                    oldToken = existing->body.getToken(parseContext, &oldPpToken);
                    newToken = mac.body.getToken(parseContext, &newPpToken);
                    // for the first token, preceding spaces don't matter
                    if (firstToken) {
                        newPpToken.space = oldPpToken.space;
                        firstToken = false;
                    }
                    if (oldToken != newToken || oldPpToken != newPpToken) {
                        parseContext.ppError(defineLoc, "Macro redefined; different substitutions:", "#define",
                            atomStrings.getString(defAtom));
                        break;
                    }
                } while (newToken != EndOfInput);
            }
        }
        *existing = mac;
    } else
        addMacroDef(defAtom, mac);

    return '\n';
}

// Handle #undef
int TPpContext::CPPundef(TPpToken* ppToken)
{
    int token = scanToken(ppToken);
    if (token != PpAtomIdentifier) {
        parseContext.ppError(ppToken->loc, "must be followed by macro name", "#undef", "");

        return token;
    }

    parseContext.reservedPpErrorCheck(ppToken->loc, ppToken->name, "#undef");

    MacroSymbol* macro = lookupMacroDef(atomStrings.getAtom(ppToken->name));
    if (macro != nullptr)
        macro->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 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;

        int nextAtom = atomStrings.getAtom(ppToken->name);
        if (nextAtom == PpAtomIf || nextAtom == PpAtomIfdef || nextAtom == PpAtomIfndef) {
            depth++;
            if (ifdepth >= maxIfNesting || elsetracker >= maxIfNesting) {
                parseContext.ppError(ppToken->loc, "maximum nesting depth exceeded", "#if/#ifdef/#ifndef", "");
                return EndOfInput;
            } else {
                ifdepth++;
                elsetracker++;
            }
        } else if (nextAtom == PpAtomEndif) {
            token = extraTokenCheck(nextAtom, ppToken, scanToken(ppToken));
            elseSeen[elsetracker] = false;
            --elsetracker;
            if (depth == 0) {
                // found the #endif we are looking for
                if (ifdepth > 0)
                    --ifdepth;
                break;
            }
            --depth;
            --ifdepth;
        } else if (matchelse && depth == 0) {
            if (nextAtom == PpAtomElse) {
                elseSeen[elsetracker] = true;
                token = extraTokenCheck(nextAtom, ppToken, scanToken(ppToken));
                // found the #else we are looking for
                break;
            } else if (nextAtom == 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 > 0) {
                    --ifdepth;
                    elseSeen[elsetracker] = false;
                    --elsetracker;
                }

                return CPPif(ppToken);
            }
        } else if (nextAtom == PpAtomElse) {
            if (elseSeen[elsetracker])
                parseContext.ppError(ppToken->loc, "#else after #else", "#else", "");
            else
                elseSeen[elsetracker] = true;
            token = extraTokenCheck(nextAtom, ppToken, scanToken(ppToken));
        } else if (nextAtom == 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 contextAtom, TPpToken* ppToken, int token)
{
    if (token != '\n' && token != EndOfInput) {
        static const char* message = "unexpected tokens following directive";

        const char* label;
        if (contextAtom == PpAtomElse)
            label = "#else";
        else if (contextAtom == PpAtomElif)
            label = "#elif";
        else if (contextAtom == PpAtomEndif)
            label = "#endif";
        else if (contextAtom == PpAtomIf)
            label = "#if";
        else if (contextAtom == 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 == INT_MIN && b == -1 ? 0 : a / b; }
    int op_mod(int a, int b) { return a == INT_MIN && b == -1 ? 0 : 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 (strcmp("defined", ppToken->name) == 0) {
            if (! parseContext.isReadingHLSL() && isMacroInput()) {
                if (parseContext.relaxedErrors())
                    parseContext.ppWarn(ppToken->loc, "nonportable when expanded from macros for preprocessor expression",
                                                      "defined", "");
                else
                    parseContext.ppError(ppToken->loc, "cannot use in preprocessor expression when expanded from macros",
                                                       "defined", "");
            }
            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;
            }

            MacroSymbol* macro = lookupMacroDef(atomStrings.getAtom(ppToken->name));
            res = macro != nullptr ? !macro->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 && strcmp("defined", ppToken->name) != 0) {
        switch (MacroExpand(ppToken, true, false)) {
        case MacroExpandNotStarted:
        case MacroExpandError:
            parseContext.ppError(ppToken->loc, "can't evaluate expression", "preprocessor evaluation", "");
            err = true;
            res = 0;
            break;
        case MacroExpandStarted:
            break;
        case MacroExpandUndef:
            if (! shortCircuit && parseContext.isEsProfile()) {
                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);
            }
            break;
        }
        token = scanToken(ppToken);
        if (err)
            break;
    }

    return token;
}

// Handle #if
int TPpContext::CPPif(TPpToken* ppToken)
{
    int token = scanToken(ppToken);
    if (ifdepth >= maxIfNesting || elsetracker >= maxIfNesting) {
        parseContext.ppError(ppToken->loc, "maximum nesting depth exceeded", "#if", "");
        return EndOfInput;
    } else {
        elsetracker++;
        ifdepth++;
    }
    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);
    if (ifdepth > maxIfNesting || elsetracker > maxIfNesting) {
        parseContext.ppError(ppToken->loc, "maximum nesting depth exceeded", "#ifdef", "");
        return EndOfInput;
    } else {
        elsetracker++;
        ifdepth++;
    }

    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 {
        MacroSymbol* macro = lookupMacroDef(atomStrings.getAtom(ppToken->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 (((macro != nullptr && !macro->undef) ? 1 : 0) != defined)
            token = CPPelse(1, ppToken);
    }

    return token;
}

// Handle #include ...
// TODO: Handle macro expansions for the header name
int TPpContext::CPPinclude(TPpToken* ppToken)
{
    const TSourceLoc directiveLoc = ppToken->loc;
    bool startWithLocalSearch = true; // to additionally include the extra "" paths
    int token = scanToken(ppToken);

    // handle <header-name>-style #include
    if (token == '<') {
        startWithLocalSearch = false;
        token = scanHeaderName(ppToken, '>');
    }
    // otherwise ppToken already has the header name and it was "header-name" style

    if (token != PpAtomConstString) {
        parseContext.ppError(directiveLoc, "must be followed by a header name", "#include", "");
        return token;
    }

    // Make a copy of the name because it will be overwritten by the next token scan.
    const std::string filename = ppToken->name;

    // See if the directive was well formed
    token = scanToken(ppToken);
    if (token != '\n') {
        if (token == EndOfInput)
            parseContext.ppError(ppToken->loc, "expected newline after header name:", "#include", "%s", filename.c_str());
        else
            parseContext.ppError(ppToken->loc, "extra content after header name:", "#include", "%s", filename.c_str());
        return token;
    }

    // Process well-formed directive

    // Find the inclusion, first look in "Local" ("") paths, if requested,
    // otherwise, only search the "System" (<>) paths.
    TShader::Includer::IncludeResult* res = nullptr;
    if (startWithLocalSearch)
        res = includer.includeLocal(filename.c_str(), currentSourceFile.c_str(), includeStack.size() + 1);
    if (res == nullptr || res->headerName.empty()) {
        includer.releaseInclude(res);
        res = includer.includeSystem(filename.c_str(), currentSourceFile.c_str(), includeStack.size() + 1);
    }

    // Process the results
    if (res != nullptr && !res->headerName.empty()) {
        if (res->headerData != nullptr && res->headerLength > 0) {
            // path for processing one or more tokens from an included header, hand off 'res'
            const bool forNextLine = parseContext.lineDirectiveShouldSetNextLine();
            std::ostringstream prologue;
            std::ostringstream epilogue;
            prologue << "#line " << forNextLine << " " << "\"" << res->headerName << "\"\n";
            epilogue << (res->headerData[res->headerLength - 1] == '\n'? "" : "\n") <<
                "#line " << directiveLoc.line + forNextLine << " " << directiveLoc.getStringNameOrNum() << "\n";
            pushInput(new TokenizableIncludeFile(directiveLoc, prologue.str(), res, epilogue.str(), this));
            parseContext.intermediate.addIncludeText(res->headerName.c_str(), res->headerData, res->headerLength);
            // There's no "current" location anymore.
            parseContext.setCurrentColumn(0);
        } else {
            // things are okay, but there is nothing to process
            includer.releaseInclude(res);
        }
    } else {
        // error path, clean up
        std::string message =
            res != nullptr ? std::string(res->headerData, res->headerLength)
                           : std::string("Could not process include directive");
        parseContext.ppError(directiveLoc, message.c_str(), "#include", "for header name: %s", filename.c_str());
        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') {
#ifndef GLSLANG_WEB
            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 = atomStrings.getString(atomStrings.getAddAtom(ppToken->name));
                parseContext.setCurrentSourceName(sourceName);
                hasFile = true;
                token = scanToken(ppToken);
            } else
#endif
            {
                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 == PpAtomConstInt16 || token == PpAtomConstUint16 ||
            token == PpAtomConstInt   || token == PpAtomConstUint   ||
            token == PpAtomConstInt64 || token == PpAtomConstUint64 ||
            token == PpAtomConstFloat16 ||
            token == PpAtomConstFloat || token == PpAtomConstDouble) {
                message.append(ppToken->name);
        } else if (token == PpAtomIdentifier || token == PpAtomConstString) {
            message.append(ppToken->name);
        } else {
            message.append(atomStrings.getString(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 PpAtomConstInt16:
        case PpAtomConstUint16:
        case PpAtomConstFloat:
        case PpAtomConstDouble:
        case PpAtomConstFloat16:
            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) {
        if (parseContext.isReadingHLSL())
            parseContext.ppError(ppToken->loc, "invalid preprocessor command", "#version", "");
        else
            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 {
        int profileAtom = atomStrings.getAtom(ppToken->name);
        if (profileAtom != PpAtomCore &&
            profileAtom != PpAtomCompatibility &&
            profileAtom != 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", "");

    snprintf(extensionName, sizeof(extensionName), "%s", 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 (atomStrings.getAtom(ppToken->name)) {
        case PpAtomDefine:
            token = CPPdefine(ppToken);
            break;
        case PpAtomElse:
            if (elseSeen[elsetracker])
                parseContext.ppError(ppToken->loc, "#else after #else", "#else", "");
            elseSeen[elsetracker] = true;
            if (ifdepth == 0)
                parseContext.ppError(ppToken->loc, "mismatched statements", "#else", "");
            token = extraTokenCheck(PpAtomElse, ppToken, scanToken(ppToken));
            token = CPPelse(0, ppToken);
            break;
        case PpAtomElif:
            if (ifdepth == 0)
                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 == 0)
                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 PpAtomLine:
            token = CPPline(ppToken);
            break;
#ifndef GLSLANG_WEB
        case PpAtomInclude:
            if(!parseContext.isReadingHLSL()) {
                parseContext.ppRequireExtensions(ppToken->loc, 1, &E_GL_GOOGLE_include_directive, "#include");
            }
            token = CPPinclude(ppToken);
            break;
        case PpAtomPragma:
            token = CPPpragma(ppToken);
            break;
#endif
        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;
}

// Context-dependent parsing of a #include <header-name>.
// Assumes no macro expansions etc. are being done; the name is just on the current input.
// Always creates a name and returns PpAtomicConstString, unless we run out of input.
int TPpContext::scanHeaderName(TPpToken* ppToken, char delimit)
{
    bool tooLong = false;

    if (inputStack.empty())
        return EndOfInput;

    int len = 0;
    ppToken->name[0] = '\0';
    do {
        int ch = inputStack.back()->getch();

        // done yet?
        if (ch == delimit) {
            ppToken->name[len] = '\0';
            if (tooLong)
                parseContext.ppError(ppToken->loc, "header name too long", "", "");
            return PpAtomConstString;
        } else if (ch == EndOfInput)
            return EndOfInput;

        // found a character to expand the name with
        if (len < MaxTokenLength)
            ppToken->name[len++] = (char)ch;
        else
            tooLong = true;
    } while (true);
}

// Macro-expand a macro argument 'arg' to create 'expandedArg'.
// Does not replace 'arg'.
// Returns nullptr if no expanded argument is created.
TPpContext::TokenStream* TPpContext::PrescanMacroArg(TokenStream& arg, TPpToken* ppToken, bool newLineOkay)
{
    // expand the argument
    TokenStream* expandedArg = new TokenStream;
    pushInput(new tMarkerInput(this));
    pushTokenStreamInput(arg);
    int token;
    while ((token = scanToken(ppToken)) != tMarkerInput::marker && token != EndOfInput) {
        token = tokenPaste(token, *ppToken);
        if (token == PpAtomIdentifier) {
            switch (MacroExpand(ppToken, false, newLineOkay)) {
            case MacroExpandNotStarted:
                break;
            case MacroExpandError:
                // toss the rest of the pushed-input argument by scanning until tMarkerInput
                while ((token = scanToken(ppToken)) != tMarkerInput::marker && token != EndOfInput)
                    ;
                break;
            case MacroExpandStarted:
            case MacroExpandUndef:
                continue;
            }
        }
        if (token == tMarkerInput::marker || token == EndOfInput)
            break;
        expandedArg->putToken(token, ppToken);
    }

    if (token != tMarkerInput::marker) {
        // Error, or MacroExpand ate the marker, so had bad input, recover
        delete expandedArg;
        expandedArg = nullptr;
    }

    return expandedArg;
}

//
// Return the next token for a macro expansion, handling macro arguments,
// whose semantics are dependent on being adjacent to ##.
//
int TPpContext::tMacroInput::scan(TPpToken* ppToken)
{
    int token;
    do {
        token = mac->body.getToken(pp->parseContext, ppToken);
    } while (token == ' ');  // handle white space in macro

    // Hash operators basically turn off a round of macro substitution
    // (the round done on the argument before the round done on the RHS of the
    // macro definition):
    //
    // "A parameter in the replacement list, unless preceded by a # or ##
    // preprocessing token or followed by a ## preprocessing token (see below),
    // is replaced by the corresponding argument after all macros contained
    // therein have been expanded."
    //
    // "If, in the replacement list, a parameter is immediately preceded or
    // followed by a ## preprocessing token, the parameter is replaced by the
    // corresponding argument's preprocessing token sequence."

    bool pasting = false;
    if (postpaste) {
        // don't expand next token
        pasting = true;
        postpaste = false;
    }

    if (prepaste) {
        // already know we should be on a ##, verify
        assert(token == PpAtomPaste);
        prepaste = false;
        postpaste = true;
    }

    // see if are preceding a ##
    if (mac->body.peekUntokenizedPasting()) {
        prepaste = true;
        pasting = true;
    }

    // HLSL does expand macros before concatenation
    if (pasting && pp->parseContext.isReadingHLSL())
        pasting = false;

    // TODO: preprocessor:  properly handle whitespace (or lack of it) between tokens when expanding
    if (token == PpAtomIdentifier) {
        int i;
        for (i = (int)mac->args.size() - 1; i >= 0; i--)
            if (strcmp(pp->atomStrings.getString(mac->args[i]), ppToken->name) == 0)
                break;
        if (i >= 0) {
            TokenStream* arg = expandedArgs[i];
            if (arg == nullptr || pasting)
                arg = args[i];
            pp->pushTokenStreamInput(*arg, prepaste);

            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;

    ppToken->name[0] = '0';
    ppToken->name[1] = 0;
    ppToken->ival = 0;
    ppToken->space = false;
    done = true;

    return PpAtomConstInt;
}

//
// Check a token 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 MacroExpandStarted.
// - If it is, but undefined, and expandUndef is requested, push a tInput
//   that will expand to 0 and return MacroExpandUndef.
// - Otherwise, there is no expansion, and there are two cases:
//   * It might be okay there is no expansion, and no specific error was
//     detected. Returns MacroExpandNotStarted.
//   * The expansion was started, but could not be completed, due to an error
//     that cannot be recovered from. Returns MacroExpandError.
//
MacroExpandResult TPpContext::MacroExpand(TPpToken* ppToken, bool expandUndef, bool newLineOkay)
{
    ppToken->space = false;
    int macroAtom = atomStrings.getAtom(ppToken->name);
    switch (macroAtom) {
    case PpAtomLineMacro:
        ppToken->ival = parseContext.getCurrentLoc().line;
        snprintf(ppToken->name, sizeof(ppToken->name), "%d", ppToken->ival);
        UngetToken(PpAtomConstInt, ppToken);
        return MacroExpandStarted;

    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 MacroExpandStarted;
    }

    case PpAtomVersionMacro:
        ppToken->ival = parseContext.version;
        snprintf(ppToken->name, sizeof(ppToken->name), "%d", ppToken->ival);
        UngetToken(PpAtomConstInt, ppToken);
        return MacroExpandStarted;

    default:
        break;
    }

    MacroSymbol* macro = macroAtom == 0 ? nullptr : lookupMacroDef(macroAtom);

    // no recursive expansions
    if (macro != nullptr && macro->busy)
        return MacroExpandNotStarted;

    // not expanding undefined macros
    if ((macro == nullptr || macro->undef) && ! expandUndef)
        return MacroExpandNotStarted;

    // 0 is the value of an undefined macro
    if ((macro == nullptr || macro->undef) && expandUndef) {
        pushInput(new tZeroInput(this));
        return MacroExpandUndef;
    }

    tMacroInput *in = new tMacroInput(this);

    TSourceLoc loc = ppToken->loc;  // in case we go to the next line before discovering the error
    in->mac = macro;
    if (macro->functionLike) {
        // We don't know yet if this will be a successful call of a
        // function-like macro; need to look for a '(', but without trashing
        // the passed in ppToken, until we know we are no longer speculative.
        TPpToken parenToken;
        int token = scanToken(&parenToken);
        if (newLineOkay) {
            while (token == '\n')
                token = scanToken(&parenToken);
        }
        if (token != '(') {
            // Function-like macro called with object-like syntax: okay, don't expand.
            // (We ate exactly one token that might not be white space; put it back.
            UngetToken(token, &parenToken);
            delete in;
            return MacroExpandNotStarted;
        }
        in->args.resize(in->mac->args.size());
        for (size_t i = 0; i < in->mac->args.size(); i++)
            in->args[i] = new TokenStream;
        in->expandedArgs.resize(in->mac->args.size());
        for (size_t i = 0; i < in->mac->args.size(); i++)
            in->expandedArgs[i] = nullptr;
        size_t arg = 0;
        bool tokenRecorded = false;
        do {
            TVector<char> nestStack;
            while (true) {
                token = scanToken(ppToken);
                if (token == EndOfInput || token == tMarkerInput::marker) {
                    parseContext.ppError(loc, "End of input in macro", "macro expansion", atomStrings.getString(macroAtom));
                    delete in;
                    return MacroExpandError;
                }
                if (token == '\n') {
                    if (! newLineOkay) {
                        parseContext.ppError(loc, "End of line in macro substitution:", "macro expansion", atomStrings.getString(macroAtom));
                        delete in;
                        return MacroExpandError;
                    }
                    continue;
                }
                if (token == '#') {
                    parseContext.ppError(ppToken->loc, "unexpected '#'", "macro expansion", atomStrings.getString(macroAtom));
                    delete in;
                    return MacroExpandError;
                }
                if (in->mac->args.size() == 0 && token != ')')
                    break;
                if (nestStack.size() == 0 && (token == ',' || token == ')'))
                    break;
                if (token == '(')
                    nestStack.push_back(')');
                else if (token == '{' && parseContext.isReadingHLSL())
                    nestStack.push_back('}');
                else if (nestStack.size() > 0 && token == nestStack.back())
                    nestStack.pop_back();
                in->args[arg]->putToken(token, ppToken);
                tokenRecorded = true;
            }
            // end of single argument scan

            if (token == ')') {
                // closing paren of call
                if (in->mac->args.size() == 1 && !tokenRecorded)
                    break;
                arg++;
                break;
            }
            arg++;
        } while (arg < in->mac->args.size());
        // end of all arguments scan

        if (arg < in->mac->args.size())
            parseContext.ppError(loc, "Too few args in Macro", "macro expansion", atomStrings.getString(macroAtom));
        else if (token != ')') {
            // Error recover code; find end of call, if possible
            int depth = 0;
            while (token != EndOfInput && (depth > 0 || token != ')')) {
                if (token == ')' || token == '}')
                    depth--;
                token = scanToken(ppToken);
                if (token == '(' || token == '{')
                    depth++;
            }

            if (token == EndOfInput) {
                parseContext.ppError(loc, "End of input in macro", "macro expansion", atomStrings.getString(macroAtom));
                delete in;
                return MacroExpandError;
            }
            parseContext.ppError(loc, "Too many args in macro", "macro expansion", atomStrings.getString(macroAtom));
        }

        // We need both expanded and non-expanded forms of the argument, for whether or
        // not token pasting will be applied later when the argument is consumed next to ##.
        for (size_t i = 0; i < in->mac->args.size(); i++)
            in->expandedArgs[i] = PrescanMacroArg(*in->args[i], ppToken, newLineOkay);
    }

    pushInput(in);
    macro->busy = 1;
    macro->body.reset();

    return MacroExpandStarted;
}

} // end namespace glslang
