Example #1
0
// 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 == tMarkerInput::marker || token == EndOfInput)
            break;
        if (token == PpAtomIdentifier && MacroExpand(ppToken, false, newLineOkay) != 0)
            continue;
        expandedArg->putToken(token, ppToken);
    }

    if (token == EndOfInput) {
        // MacroExpand ate the marker, so had bad input, recover
        delete expandedArg;
        expandedArg = nullptr;
    } else {
        // remove the marker
        popInput();
    }

    return expandedArg;
}
Example #2
0
// 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;
}
Example #3
0
//
// The main functional entry point into the preprocessor, which will
// scan the source strings to figure out and return the next processing token.
//
// Return the token, or EndOfInput when no more tokens.
//
int TPpContext::tokenize(TPpToken& ppToken)
{
    for(;;) {
        int token = scanToken(&ppToken);

        // Handle token-pasting logic
        token = tokenPaste(token, ppToken);

        if (token == EndOfInput) {
            missingEndifCheck();
            return EndOfInput;
        }
        if (token == '#') {
            if (previous_token == '\n') {
                token = readCPPline(&ppToken);
                if (token == EndOfInput) {
                    missingEndifCheck();
                    return EndOfInput;
                }
                continue;
            } else {
                _parseContext.ppError(ppToken.loc, "preprocessor directive cannot be preceded by another token", "#", "");
                return EndOfInput;
            }
        }
        previous_token = token;

        if (token == '\n')
            continue;

        // expand macros
        if (token == PpAtomIdentifier && MacroExpand(&ppToken, false, true) != 0)
            continue;

        switch (token) {
        case PpAtomIdentifier:
        case PpAtomConstInt:
        case PpAtomConstUint:
        case PpAtomConstFloat:
        case PpAtomConstInt64:
        case PpAtomConstUint64:
        case PpAtomConstInt16:
        case PpAtomConstUint16:
        case PpAtomConstDouble:
        case PpAtomConstFloat16:
            if (ppToken.name[0] == '\0')
                continue;
            break;
        case PpAtomConstString:
            if (ifdepth == 0 && _parseContext.intermediate.getSource() != EShSourceHlsl) {
                // HLSL allows string literals.
                _parseContext.ppError(ppToken.loc, "string literals not supported", "\"\"", "");
                continue;
            }
            break;
        case '\'':
            _parseContext.ppError(ppToken.loc, "character literals not supported", "\'", "");
            continue;
        default:
            strcpy(ppToken.name, atomStrings.getString(token));
            break;
        }

        return token;
    }
}