bool MacroExpander::expandMacro(const Macro ¯o, 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; }
bool MacroExpander::expandMacro(const Macro ¯o, 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; }