Exemple #1
0
static int CPPelse(int matchelse, yystypepp * yylvalpp)
{
    int atom,depth=0;
    int token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
	
	while (token > 0) {
        if (token != '#') {
		    while (token != '\n')
                token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
            
            token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
            continue;
        }
		if ((token = cpp->currentInput->scan(cpp->currentInput, yylvalpp)) != CPP_IDENTIFIER)
			continue;
        atom = yylvalpp->sc_ident;
        if (atom == ifAtom || atom == ifdefAtom || atom == ifndefAtom){
            depth++; cpp->ifdepth++; cpp->elsetracker++;
            cpp->elsedepth[cpp->elsetracker] = 0;
		}
		else if (atom == endifAtom) {
            if(--depth<0){
			    --cpp->elsetracker;
                if (cpp->ifdepth) 
                    --cpp->ifdepth;
                break;
            }             
                --cpp->elsetracker;
                --cpp->ifdepth;
            }
        else if (((int)(matchelse) != 0)&& depth==0) {
			if (atom == elseAtom ) {
                token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
                if (token != '\n') {
                    CPPWarningToInfoLog("unexpected tokens following #else preprocessor directive - expected a newline");
                    while (token != '\n')
                        token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
                } 
				break;
			} 
			else if (atom == elifAtom) {
                /* we decrement cpp->ifdepth here, because CPPif will increment
                 * it and we really want to leave it alone */
				if (cpp->ifdepth){
					--cpp->ifdepth;
				    --cpp->elsetracker;
				}
                return CPPif(yylvalpp);
            }
		}
        else if((atom==elseAtom) && (!ChkCorrectElseNesting())){
            CPPErrorToInfoLog("#else after a #else");
            cpp->CompileError=1;
        }
	};
    return token;
}
Exemple #2
0
static int CPPelse(yystypepp* yylvalpp)
{
    int token = CPPgotoEndOfIfBlock(1, yylvalpp);
    if (yylvalpp->sc_ident == endifAtom)
    {
        cpp->ifdepth--;
        token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
    }
    else if (yylvalpp->sc_ident == elifAtom)
    {
        cpp->ifdepth--; // will be reincremented by CPPif
        token = CPPif(yylvalpp);
    }
    else if (yylvalpp->sc_ident == elseAtom)
        token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
    else
    {
        CPPErrorToInfoLog("unclosed #if block");
        return 0;
    }
}
Exemple #3
0
int readCPPline(yystypepp * yylvalpp)
{
    int token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
    const char *message;

    if (token == CPP_IDENTIFIER) {
        if (yylvalpp->sc_ident == defineAtom) {
             token = CPPdefine(yylvalpp);
        } else if (yylvalpp->sc_ident == elseAtom) {
			 if(ChkCorrectElseNesting()){
                 if (!cpp->ifdepth ){
                     CPPErrorToInfoLog("#else mismatch");
                     cpp->CompileError=1;
                     return 0;
                 }
                 token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
                 if (token != '\n') {
                     CPPWarningToInfoLog("unexpected tokens following #else preprocessor directive - expected a newline");
                     while (token != '\n') {
                         token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
                         if (token <= 0) { // EOF or error
                             CPPErrorToInfoLog("unexpected end of input in #ifdef preprocessor directive - expected a newline");
                             return 0;
                         }
                     }
                 }
			     token = CPPelse(0, yylvalpp);
             }else{
                 CPPErrorToInfoLog("#else after a #else");
                 cpp->ifdepth = 0;
                 cpp->elsetracker = 0;
                 cpp->pastFirstStatement = 1;
                 cpp->CompileError = 1;
                 return 0;
             }
		} else if (yylvalpp->sc_ident == elifAtom) {
            if (!cpp->ifdepth){
                 CPPErrorToInfoLog("#elif mismatch");
                 cpp->CompileError=1;
                 return 0;
            } 
            // this token is really a dont care, but we still need to eat the tokens
            token = cpp->currentInput->scan(cpp->currentInput, yylvalpp); 
            while (token != '\n') {
                token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
                if (token <= 0) { // EOF or error
                    CPPErrorToInfoLog("unexpect tokens following #elif preprocessor directive - expected a newline");
                    cpp->CompileError = 1;
                    return 0;
                }
            }
		    token = CPPelse(0, yylvalpp);
        } else if (yylvalpp->sc_ident == endifAtom) {
             if (!cpp->ifdepth){
                 CPPErrorToInfoLog("#endif mismatch");
                 cpp->CompileError=1;
                 return 0;
             }
             else
                 --cpp->ifdepth;

             if (cpp->elsetracker)
                 --cpp->elsetracker;

	    } else if (yylvalpp->sc_ident == ifAtom) {
             token = CPPif(yylvalpp);
        } else if (yylvalpp->sc_ident == ifdefAtom) {
             token = CPPifdef(1, yylvalpp);
        } else if (yylvalpp->sc_ident == ifndefAtom) {
             token = CPPifdef(0, yylvalpp);
        } else if (yylvalpp->sc_ident == lineAtom) {
             token = CPPline(yylvalpp);
        } else if (yylvalpp->sc_ident == pragmaAtom) {
             token = CPPpragma(yylvalpp);
        } else if (yylvalpp->sc_ident == undefAtom) {
             token = CPPundef(yylvalpp);
        } else if (yylvalpp->sc_ident == errorAtom) {
             token = CPPerror(yylvalpp);
        } else if (yylvalpp->sc_ident == versionAtom) {
            token = CPPversion(yylvalpp);
        } else if (yylvalpp->sc_ident == extensionAtom) {
            token = CPPextension(yylvalpp);
        } else {
            StoreStr("Invalid Directive");
            StoreStr(GetStringOfAtom(atable,yylvalpp->sc_ident));
            message=GetStrfromTStr();
            CPPShInfoLogMsg(message);
            ResetTString();
        }
    }
    while (token != '\n' && token != 0 && token != EOF) {
		token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
	}
        
    cpp->pastFirstStatement = 1;

    return token;
} // readCPPline
Exemple #4
0
int TPpContext::readCPPline(TPpToken * yylvalpp)
{
    int token = currentInput->scan(this, currentInput, yylvalpp);
    bool isVersion = false;

    if (token == CPP_IDENTIFIER) {
        if (yylvalpp->atom == defineAtom) {
            token = CPPdefine(yylvalpp);
        } else if (yylvalpp->atom == elseAtom) {
            if (ChkCorrectElseNesting()) {
                if (! ifdepth) {
                    parseContext.error(yylvalpp->loc, "mismatched statements", "#else", "");
                }
                token = currentInput->scan(this, currentInput, yylvalpp);
                if (token != '\n') {                     
                    parseContext.warn(yylvalpp->loc, "unexpected tokens following #else directive - expected a newline", "#else", "");
                    while (token != '\n')
                        token = currentInput->scan(this, currentInput, yylvalpp);
                }
                token = CPPelse(0, yylvalpp);
            } else {
                parseContext.error(yylvalpp->loc, "#else after a #else", "#else", "");
                ifdepth = 0;
                notAVersionToken = true;
                return 0;
            }
        } else if (yylvalpp->atom == elifAtom) {
            if (! ifdepth) {
                parseContext.error(yylvalpp->loc, "mismatched statements", "#elif", "");
            } 
            // this token is really a dont care, but we still need to eat the tokens
            token = currentInput->scan(this, currentInput, yylvalpp); 
            while (token != '\n')
                token = currentInput->scan(this, currentInput, yylvalpp);
            token = CPPelse(0, yylvalpp);
        } else if (yylvalpp->atom == endifAtom) {
            elsedepth[elsetracker] = 0;
            --elsetracker;
            if (! ifdepth)
                parseContext.error(yylvalpp->loc, "mismatched statements", "#endif", "");
            else
                --ifdepth;
        } else if (yylvalpp->atom == ifAtom) {
            token = CPPif (yylvalpp);
        } else if (yylvalpp->atom == ifdefAtom) {
            token = CPPifdef(1, yylvalpp);
        } else if (yylvalpp->atom == ifndefAtom) {
            token = CPPifdef(0, yylvalpp);
        } else if (yylvalpp->atom == lineAtom) {
            token = CPPline(yylvalpp);
        } else if (yylvalpp->atom == pragmaAtom) {
            token = CPPpragma(yylvalpp);
        } else if (yylvalpp->atom == undefAtom) {
            token = CPPundef(yylvalpp);
        } else if (yylvalpp->atom == errorAtom) {
            token = CPPerror(yylvalpp);
        } else if (yylvalpp->atom == versionAtom) {
            token = CPPversion(yylvalpp);
            isVersion = true;
        } else if (yylvalpp->atom == extensionAtom) {
            token = CPPextension(yylvalpp);
        } else {
            parseContext.error(yylvalpp->loc, "Invalid Directive", "#", GetStringOfAtom(&atomTable, yylvalpp->atom));
        }
    }
    while (token != '\n' && token != 0 && token != EOF) {
        token = currentInput->scan(this, currentInput, yylvalpp);
    }

    notAVersionToken = ! isVersion;

    return token;
} // readCPPline
Exemple #5
0
int TPpContext::CPPelse(int matchelse, TPpToken * yylvalpp)
{
    int atom;
    int depth = 0;
    int token = currentInput->scan(this, currentInput, yylvalpp);

    while (token > 0) {
        if (token != '#') {
            while (token != '\n')
                token = currentInput->scan(this, currentInput, yylvalpp);

            token = currentInput->scan(this, currentInput, yylvalpp);
            continue;
        }

        if ((token = currentInput->scan(this, currentInput, yylvalpp)) != CPP_IDENTIFIER)
            continue;

        atom = yylvalpp->atom;
        if (atom == ifAtom || atom == ifdefAtom || atom == ifndefAtom) {
            depth++; 
            ifdepth++; 
            elsetracker++;
        } else if (atom == endifAtom) {
            elsedepth[elsetracker] = 0;
            --elsetracker;
            if (depth == 0) {
                // found the #endif we are looking for
                if (ifdepth) 
                    --ifdepth;
                break;
            }
            --depth;
            --ifdepth;
        } else if (matchelse && depth == 0) {
            if (atom == elseAtom ) {
                // found the #else we are looking for
                token = currentInput->scan(this, currentInput, yylvalpp);
                if (token != '\n') {
                    parseContext.warn(yylvalpp->loc, "#else", "unexpected tokens following #else directive - expected a newline", "");
                    while (token != '\n')
                        token = currentInput->scan(this, currentInput, yylvalpp);
                } 
                break;
            } else if (atom == elifAtom) {
                /* we decrement ifdepth here, because CPPif will increment
                * it and we really want to leave it alone */
                if (ifdepth) {
                    --ifdepth;
                    elsedepth[elsetracker] = 0;
                    --elsetracker;
                }

                return CPPif (yylvalpp);
            }
        } else if ((atom == elseAtom) && (!ChkCorrectElseNesting()))
            parseContext.error(yylvalpp->loc, "#else after #else", "#else", "");
    };  // end while

    return token;
}
Exemple #6
0
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:
            elseSeen[elsetracker] = false;
            --elsetracker;
            if (! ifdepth)
                parseContext.ppError(ppToken->loc, "mismatched statements", "#endif", "");
            else
                --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;
}
Exemple #7
0
/* 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;
}
Exemple #8
0
int readCPPline(yystypepp * yylvalpp)
{
    int token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
    const char *message;
    int isVersion = 0;
	
    if (token == CPP_IDENTIFIER) {
        if (yylvalpp->sc_ident == defineAtom) {
			token = CPPdefine(yylvalpp);
        } else if (yylvalpp->sc_ident == elseAtom) {
            token = CPPgotoEndOfIfBlock(1, yylvalpp);
            if (yylvalpp->sc_ident != endifAtom)
            {
                CPPErrorToInfoLog("#else or #elif mismatch");
                cpp->CompileError=1;
            }
            token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
            if (token != '\n')
                CPPWarningToInfoLog("unexpected tokens following #else preprocessor directive - expected a newline");
			
			if (!cpp->ifdepth){
				CPPErrorToInfoLog("#else or #elif mismatch");
				cpp->CompileError=1;
			}
			else
				--cpp->ifdepth;
        } else if (yylvalpp->sc_ident == elifAtom) {
            token = CPPgotoEndOfIfBlock(0, yylvalpp);
            assert(yylvalpp->sc_ident == endifAtom);
            token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
            if (!cpp->ifdepth){
                CPPErrorToInfoLog("#else or #elif mismatch");
                cpp->CompileError=1;
            }
            else
                --cpp->ifdepth;
        } else if (yylvalpp->sc_ident == endifAtom) {
			if (!cpp->ifdepth){
				CPPErrorToInfoLog("#endif mismatch");
				cpp->CompileError=1;
			}
			else
				--cpp->ifdepth;
        } else if (yylvalpp->sc_ident == ifAtom) {
			token = CPPif(yylvalpp);
        } else if (yylvalpp->sc_ident == ifdefAtom) {
			token = CPPifdef(1, yylvalpp);
        } else if (yylvalpp->sc_ident == ifndefAtom) {
			token = CPPifdef(0, yylvalpp);
        } else if (yylvalpp->sc_ident == lineAtom) {
			token = CPPline(yylvalpp);
        } else if (yylvalpp->sc_ident == pragmaAtom) {
			token = CPPpragma(yylvalpp);
        } else if (yylvalpp->sc_ident == undefAtom) {
			token = CPPundef(yylvalpp);
        } else if (yylvalpp->sc_ident == errorAtom) {
			token = CPPerror(yylvalpp);
        } else if (yylvalpp->sc_ident == versionAtom) {
            token = CPPversion(yylvalpp);
            isVersion = 1;
        } else {
            StoreStr("Invalid Directive");
            StoreStr(GetStringOfAtom(atable,yylvalpp->sc_ident));
            message=GetStrfromTStr();
            CPPShInfoLogMsg(message);
            ResetTString();
        }
    }
    while (token != '\n' && token != 0 && token != EOF) {
        token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
    }
	
    cpp->notAVersionToken = !isVersion;
	
    return token;
} // readCPPline
Exemple #9
0
int TPpContext::readCPPline(TPpToken* ppToken)
{
    int token = currentInput->scan(this, currentInput, ppToken);
    bool isVersion = false;

    if (token == CPP_IDENTIFIER) {
        if (ppToken->atom == defineAtom) {
            token = CPPdefine(ppToken);
        } else if (ppToken->atom == elseAtom) {
            if (! elsetracker[elseSeen]) {
                elsetracker[elseSeen] = true;
                if (! ifdepth)
                    parseContext.error(ppToken->loc, "mismatched statements", "#else", "");
                token = extraTokenCheck(elseAtom, ppToken, currentInput->scan(this, currentInput, ppToken));
                token = CPPelse(0, ppToken);
            } else {
                parseContext.error(ppToken->loc, "#else after a #else", "#else", "");
                ifdepth = 0;
                return 0;
            }
        } else if (ppToken->atom == elifAtom) {
            if (! ifdepth)
                parseContext.error(ppToken->loc, "mismatched statements", "#elif", "");
            // this token is really a dont care, but we still need to eat the tokens
            token = currentInput->scan(this, currentInput, ppToken); 
            while (token != '\n')
                token = currentInput->scan(this, currentInput, ppToken);
            token = CPPelse(0, ppToken);
        } else if (ppToken->atom == endifAtom) {
            elseSeen[elsetracker] = false;
            --elsetracker;
            if (! ifdepth)
                parseContext.error(ppToken->loc, "mismatched statements", "#endif", "");
            else
                --ifdepth;
            token = extraTokenCheck(endifAtom, ppToken, currentInput->scan(this, currentInput, ppToken));
        } else if (ppToken->atom == ifAtom) {
            token = CPPif (ppToken);
        } else if (ppToken->atom == ifdefAtom) {
            token = CPPifdef(1, ppToken);
        } else if (ppToken->atom == ifndefAtom) {
            token = CPPifdef(0, ppToken);
        } else if (ppToken->atom == lineAtom) {
            token = CPPline(ppToken);
        } else if (ppToken->atom == pragmaAtom) {
            token = CPPpragma(ppToken);
        } else if (ppToken->atom == undefAtom) {
            token = CPPundef(ppToken);
        } else if (ppToken->atom == errorAtom) {
            token = CPPerror(ppToken);
        } else if (ppToken->atom == versionAtom) {
            token = CPPversion(ppToken);
            isVersion = true;
        } else if (ppToken->atom == extensionAtom) {
            token = CPPextension(ppToken);
        } else {
            parseContext.error(ppToken->loc, "invalid directive:", "#", GetAtomString(ppToken->atom));
        }
    } else if (token != '\n' && token > 0)
        parseContext.error(ppToken->loc, "invalid directive", "#", "");

    while (token != '\n' && token != 0 && token != EOF)
        token = currentInput->scan(this, currentInput, ppToken);

    return token;
}
Exemple #10
0
/* 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 = currentInput->scan(this, currentInput, ppToken);

    while (token != EOF) {
        if (token != '#') {
            while (token != '\n' && token != EOF)
                token = currentInput->scan(this, currentInput, ppToken);
            
            if (token == EOF)
                return EOF;

            token = currentInput->scan(this, currentInput, ppToken);
            continue;
        }

        if ((token = currentInput->scan(this, currentInput, ppToken)) != CPP_IDENTIFIER)
            continue;

        atom = ppToken->atom;
        if (atom == ifAtom || atom == ifdefAtom || atom == ifndefAtom) {
            depth++; 
            ifdepth++; 
            elsetracker++;
        } else if (atom == endifAtom) {
            token = extraTokenCheck(atom, ppToken, currentInput->scan(this, currentInput, 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 == elseAtom ) {
                token = extraTokenCheck(atom, ppToken, currentInput->scan(this, currentInput, ppToken));
                // found the #else we are looking for
                break;
            } else if (atom == elifAtom) {
                /* 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 == elseAtom) {
            if (elseSeen[elsetracker])
                parseContext.error(ppToken->loc, "#else after #else", "#else", "");
            else
                elseSeen[elsetracker] = true;
            token = extraTokenCheck(atom, ppToken, currentInput->scan(this, currentInput, ppToken));
        } else if (atom == elifAtom) {
            if (elseSeen[elsetracker])
                parseContext.error(ppToken->loc, "#elif after #else", "#else", "");
        }
    }

    return token;
}