Exemplo n.º 1
0
void
PreProcessor::applyMacro(const String &ident, const ref<MacroDef> &macro)
{
	assert(tokenit.is(_IDENT));
	
	DBG("apply macro: %s", ident.c_str());
	if (macro->params.empty()) {
		tokenit.erase(1);//erase identifier
		tokenit.insert(macro->tokens);
	} else {
		TokenIterator tag = tokenit;
		tokenit.next();
		//get caller params
		if (tokenit.is(_LPAREN)) {
			tokenit.next();
			List<List<Token> > caller_params;
			if (!parseFunctionParams(caller_params)) {
				ERROR("failed to parse function macro");
				return;
			}
			if (macro->params.size() != caller_params.size()) {
				ERROR("macro %s requres %d parameters", 
					  ident.c_str(), macro->params.size());
				return;
			}
			tag.erase(tokenit-tag);//erase function call tokens

			//replace macro params
			List<Token> replace_tokens = replaceMacroParams(macro->tokens, caller_params);
			tokenit.insert(replace_tokens);
			//tokenit.next();
		}
	}
}
Exemplo n.º 2
0
bool MacroExpander::expandMacro(const Macro &macro,
                                const Token &identifier,
                                std::vector<Token> *replacements)
{
    replacements->clear();

    // In the case of an object-like macro, the replacement list gets its location
    // from the identifier, but in the case of a function-like macro, the replacement
    // list gets its location from the closing parenthesis of the macro invocation.
    // This is tested by dEQP-GLES3.functional.shaders.preprocessor.predefined_macros.*
    SourceLocation replacementLocation = identifier.location;
    if (macro.type == Macro::kTypeObj)
    {
        replacements->assign(macro.replacements.begin(),
                             macro.replacements.end());

        if (macro.predefined)
        {
            const char kLine[] = "__LINE__";
            const char kFile[] = "__FILE__";

            ASSERT(replacements->size() == 1);
            Token& repl = replacements->front();
            if (macro.name == kLine)
            {
                repl.text = ToString(identifier.location.line);
            }
            else if (macro.name == kFile)
            {
                repl.text = ToString(identifier.location.file);
            }
        }
    }
    else
    {
        ASSERT(macro.type == Macro::kTypeFunc);
        std::vector<MacroArg> args;
        args.reserve(macro.parameters.size());
        if (!collectMacroArgs(macro, identifier, &args, &replacementLocation))
            return false;

        replaceMacroParams(macro, args, replacements);
    }

    for (std::size_t i = 0; i < replacements->size(); ++i)
    {
        Token& repl = replacements->at(i);
        if (i == 0)
        {
            // The first token in the replacement list inherits the padding
            // properties of the identifier token.
            repl.setAtStartOfLine(identifier.atStartOfLine());
            repl.setHasLeadingSpace(identifier.hasLeadingSpace());
        }
        repl.location = replacementLocation;
    }
    return true;
}
Exemplo n.º 3
0
bool MacroExpander::expandMacro(const Macro &macro,
                                const Token &identifier,
                                std::vector<Token> *replacements)
{
    replacements->clear();
    if (macro.type == Macro::kTypeObj)
    {
        replacements->assign(macro.replacements.begin(),
                             macro.replacements.end());

        if (macro.predefined)
        {
            const char kLine[] = "__LINE__";
            const char kFile[] = "__FILE__";

            assert(replacements->size() == 1);
            Token& repl = replacements->front();
            if (macro.name == kLine)
            {
                std::ostringstream stream;
                stream << identifier.location.line;
                repl.text = stream.str();
            }
            else if (macro.name == kFile)
            {
                std::ostringstream stream;
                stream << identifier.location.file;
                repl.text = stream.str();
            }
        }
    }
    else
    {
        assert(macro.type == Macro::kTypeFunc);
        std::vector<MacroArg> args;
        args.reserve(macro.parameters.size());
        if (!collectMacroArgs(macro, identifier, &args))
            return false;

        replaceMacroParams(macro, args, replacements);
    }

    for (std::size_t i = 0; i < replacements->size(); ++i)
    {
        Token& repl = replacements->at(i);
        if (i == 0)
        {
            // The first token in the replacement list inherits the padding
            // properties of the identifier token.
            repl.setAtStartOfLine(identifier.atStartOfLine());
            repl.setHasLeadingSpace(identifier.hasLeadingSpace());
        }
        repl.location = identifier.location;
    }
    return true;
}