diff options
Diffstat (limited to 'src/3rdparty/angle/src/compiler/preprocessor/DirectiveParser.cpp')
-rw-r--r-- | src/3rdparty/angle/src/compiler/preprocessor/DirectiveParser.cpp | 630 |
1 files changed, 346 insertions, 284 deletions
diff --git a/src/3rdparty/angle/src/compiler/preprocessor/DirectiveParser.cpp b/src/3rdparty/angle/src/compiler/preprocessor/DirectiveParser.cpp index 2faa331378..f6c5763990 100644 --- a/src/3rdparty/angle/src/compiler/preprocessor/DirectiveParser.cpp +++ b/src/3rdparty/angle/src/compiler/preprocessor/DirectiveParser.cpp @@ -4,21 +4,22 @@ // found in the LICENSE file. // -#include "DirectiveParser.h" +#include "compiler/preprocessor/DirectiveParser.h" #include <algorithm> -#include <cassert> #include <cstdlib> #include <sstream> -#include "DiagnosticsBase.h" -#include "DirectiveHandlerBase.h" -#include "ExpressionParser.h" -#include "MacroExpander.h" -#include "Token.h" -#include "Tokenizer.h" +#include "common/debug.h" +#include "compiler/preprocessor/DiagnosticsBase.h" +#include "compiler/preprocessor/DirectiveHandlerBase.h" +#include "compiler/preprocessor/ExpressionParser.h" +#include "compiler/preprocessor/MacroExpander.h" +#include "compiler/preprocessor/Token.h" +#include "compiler/preprocessor/Tokenizer.h" -namespace { +namespace +{ enum DirectiveType { DIRECTIVE_NONE, @@ -39,19 +40,19 @@ enum DirectiveType DirectiveType getDirective(const pp::Token *token) { - const char kDirectiveDefine[] = "define"; - const char kDirectiveUndef[] = "undef"; - const char kDirectiveIf[] = "if"; - const char kDirectiveIfdef[] = "ifdef"; - const char kDirectiveIfndef[] = "ifndef"; - const char kDirectiveElse[] = "else"; - const char kDirectiveElif[] = "elif"; - const char kDirectiveEndif[] = "endif"; - const char kDirectiveError[] = "error"; - const char kDirectivePragma[] = "pragma"; + const char kDirectiveDefine[] = "define"; + const char kDirectiveUndef[] = "undef"; + const char kDirectiveIf[] = "if"; + const char kDirectiveIfdef[] = "ifdef"; + const char kDirectiveIfndef[] = "ifndef"; + const char kDirectiveElse[] = "else"; + const char kDirectiveElif[] = "elif"; + const char kDirectiveEndif[] = "endif"; + const char kDirectiveError[] = "error"; + const char kDirectivePragma[] = "pragma"; const char kDirectiveExtension[] = "extension"; - const char kDirectiveVersion[] = "version"; - const char kDirectiveLine[] = "line"; + const char kDirectiveVersion[] = "version"; + const char kDirectiveLine[] = "line"; if (token->type != pp::Token::IDENTIFIER) return DIRECTIVE_NONE; @@ -90,15 +91,15 @@ bool isConditionalDirective(DirectiveType directive) { switch (directive) { - case DIRECTIVE_IF: - case DIRECTIVE_IFDEF: - case DIRECTIVE_IFNDEF: - case DIRECTIVE_ELSE: - case DIRECTIVE_ELIF: - case DIRECTIVE_ENDIF: - return true; - default: - return false; + case DIRECTIVE_IF: + case DIRECTIVE_IFDEF: + case DIRECTIVE_IFNDEF: + case DIRECTIVE_ELSE: + case DIRECTIVE_ELIF: + case DIRECTIVE_ENDIF: + return true; + default: + return false; } } @@ -110,7 +111,7 @@ bool isEOD(const pp::Token *token) void skipUntilEOD(pp::Lexer *lexer, pp::Token *token) { - while(!isEOD(token)) + while (!isEOD(token)) { lexer->lex(token); } @@ -118,8 +119,8 @@ void skipUntilEOD(pp::Lexer *lexer, pp::Token *token) bool isMacroNameReserved(const std::string &name) { - // Names prefixed with "GL_" are reserved. - return (name.substr(0, 3) == "GL_"); + // Names prefixed with "GL_" and the name "defined" are reserved. + return name == "defined" || (name.substr(0, 3) == "GL_"); } bool hasDoubleUnderscores(const std::string &name) @@ -127,11 +128,10 @@ bool hasDoubleUnderscores(const std::string &name) return (name.find("__") != std::string::npos); } -bool isMacroPredefined(const std::string &name, - const pp::MacroSet ¯oSet) +bool isMacroPredefined(const std::string &name, const pp::MacroSet ¯oSet) { pp::MacroSet::const_iterator iter = macroSet.find(name); - return iter != macroSet.end() ? iter->second.predefined : false; + return iter != macroSet.end() ? iter->second->predefined : false; } } // namespace anonymous @@ -139,17 +139,83 @@ bool isMacroPredefined(const std::string &name, namespace pp { +class DefinedParser : public Lexer +{ + public: + DefinedParser(Lexer *lexer, const MacroSet *macroSet, Diagnostics *diagnostics) + : mLexer(lexer), mMacroSet(macroSet), mDiagnostics(diagnostics) + { + } + + protected: + void lex(Token *token) override + { + const char kDefined[] = "defined"; + + mLexer->lex(token); + if (token->type != Token::IDENTIFIER) + return; + if (token->text != kDefined) + return; + + bool paren = false; + mLexer->lex(token); + if (token->type == '(') + { + paren = true; + mLexer->lex(token); + } + + if (token->type != Token::IDENTIFIER) + { + mDiagnostics->report(Diagnostics::PP_UNEXPECTED_TOKEN, token->location, token->text); + skipUntilEOD(mLexer, token); + return; + } + MacroSet::const_iterator iter = mMacroSet->find(token->text); + std::string expression = iter != mMacroSet->end() ? "1" : "0"; + + if (paren) + { + mLexer->lex(token); + if (token->type != ')') + { + mDiagnostics->report(Diagnostics::PP_UNEXPECTED_TOKEN, token->location, + token->text); + skipUntilEOD(mLexer, token); + return; + } + } + + // We have a valid defined operator. + // Convert the current token into a CONST_INT token. + token->type = Token::CONST_INT; + token->text = expression; + } + + private: + Lexer *mLexer; + const MacroSet *mMacroSet; + Diagnostics *mDiagnostics; +}; + DirectiveParser::DirectiveParser(Tokenizer *tokenizer, MacroSet *macroSet, Diagnostics *diagnostics, - DirectiveHandler *directiveHandler) + DirectiveHandler *directiveHandler, + int maxMacroExpansionDepth) : mPastFirstStatement(false), mSeenNonPreprocessorToken(false), mTokenizer(tokenizer), mMacroSet(macroSet), mDiagnostics(diagnostics), mDirectiveHandler(directiveHandler), - mShaderVersion(100) + mShaderVersion(100), + mMaxMacroExpansionDepth(maxMacroExpansionDepth) +{ +} + +DirectiveParser::~DirectiveParser() { } @@ -174,21 +240,20 @@ void DirectiveParser::lex(Token *token) if (!mConditionalStack.empty()) { const ConditionalBlock &block = mConditionalStack.back(); - mDiagnostics->report(Diagnostics::PP_CONDITIONAL_UNTERMINATED, - block.location, block.type); + mDiagnostics->report(Diagnostics::PP_CONDITIONAL_UNTERMINATED, block.location, + block.type); } break; } - } - while (skipping() || (token->type == '\n')); + } while (skipping() || (token->type == '\n')); mPastFirstStatement = true; } void DirectiveParser::parseDirective(Token *token) { - assert(token->type == Token::PP_HASH); + ASSERT(token->type == Token::PP_HASH); mTokenizer->lex(token); if (isEOD(token)) @@ -207,86 +272,83 @@ void DirectiveParser::parseDirective(Token *token) return; } - switch(directive) + switch (directive) { - case DIRECTIVE_NONE: - mDiagnostics->report(Diagnostics::PP_DIRECTIVE_INVALID_NAME, - token->location, token->text); - skipUntilEOD(mTokenizer, token); - break; - case DIRECTIVE_DEFINE: - parseDefine(token); - break; - case DIRECTIVE_UNDEF: - parseUndef(token); - break; - case DIRECTIVE_IF: - parseIf(token); - break; - case DIRECTIVE_IFDEF: - parseIfdef(token); - break; - case DIRECTIVE_IFNDEF: - parseIfndef(token); - break; - case DIRECTIVE_ELSE: - parseElse(token); - break; - case DIRECTIVE_ELIF: - parseElif(token); - break; - case DIRECTIVE_ENDIF: - parseEndif(token); - break; - case DIRECTIVE_ERROR: - parseError(token); - break; - case DIRECTIVE_PRAGMA: - parsePragma(token); - break; - case DIRECTIVE_EXTENSION: - parseExtension(token); - break; - case DIRECTIVE_VERSION: - parseVersion(token); - break; - case DIRECTIVE_LINE: - parseLine(token); - break; - default: - assert(false); - break; + case DIRECTIVE_NONE: + mDiagnostics->report(Diagnostics::PP_DIRECTIVE_INVALID_NAME, token->location, + token->text); + skipUntilEOD(mTokenizer, token); + break; + case DIRECTIVE_DEFINE: + parseDefine(token); + break; + case DIRECTIVE_UNDEF: + parseUndef(token); + break; + case DIRECTIVE_IF: + parseIf(token); + break; + case DIRECTIVE_IFDEF: + parseIfdef(token); + break; + case DIRECTIVE_IFNDEF: + parseIfndef(token); + break; + case DIRECTIVE_ELSE: + parseElse(token); + break; + case DIRECTIVE_ELIF: + parseElif(token); + break; + case DIRECTIVE_ENDIF: + parseEndif(token); + break; + case DIRECTIVE_ERROR: + parseError(token); + break; + case DIRECTIVE_PRAGMA: + parsePragma(token); + break; + case DIRECTIVE_EXTENSION: + parseExtension(token); + break; + case DIRECTIVE_VERSION: + parseVersion(token); + break; + case DIRECTIVE_LINE: + parseLine(token); + break; + default: + UNREACHABLE(); + break; } skipUntilEOD(mTokenizer, token); if (token->type == Token::LAST) { - mDiagnostics->report(Diagnostics::PP_EOF_IN_DIRECTIVE, - token->location, token->text); + mDiagnostics->report(Diagnostics::PP_EOF_IN_DIRECTIVE, token->location, token->text); } } void DirectiveParser::parseDefine(Token *token) { - assert(getDirective(token) == DIRECTIVE_DEFINE); + ASSERT(getDirective(token) == DIRECTIVE_DEFINE); mTokenizer->lex(token); if (token->type != Token::IDENTIFIER) { - mDiagnostics->report(Diagnostics::PP_UNEXPECTED_TOKEN, - token->location, token->text); + mDiagnostics->report(Diagnostics::PP_UNEXPECTED_TOKEN, token->location, token->text); return; } if (isMacroPredefined(token->text, *mMacroSet)) { - mDiagnostics->report(Diagnostics::PP_MACRO_PREDEFINED_REDEFINED, - token->location, token->text); + mDiagnostics->report(Diagnostics::PP_MACRO_PREDEFINED_REDEFINED, token->location, + token->text); return; } if (isMacroNameReserved(token->text)) { - mDiagnostics->report(Diagnostics::PP_MACRO_NAME_RESERVED, - token->location, token->text); + mDiagnostics->report(Diagnostics::PP_MACRO_NAME_RESERVED, token->location, token->text); return; } // Using double underscores is allowed, but may result in unintended @@ -300,39 +362,37 @@ void DirectiveParser::parseDefine(Token *token) token->text); } - Macro macro; - macro.type = Macro::kTypeObj; - macro.name = token->text; + std::shared_ptr<Macro> macro = std::make_shared<Macro>(); + macro->type = Macro::kTypeObj; + macro->name = token->text; mTokenizer->lex(token); if (token->type == '(' && !token->hasLeadingSpace()) { // Function-like macro. Collect arguments. - macro.type = Macro::kTypeFunc; + macro->type = Macro::kTypeFunc; do { mTokenizer->lex(token); if (token->type != Token::IDENTIFIER) break; - if (std::find(macro.parameters.begin(), macro.parameters.end(), token->text) != macro.parameters.end()) + if (std::find(macro->parameters.begin(), macro->parameters.end(), token->text) != + macro->parameters.end()) { mDiagnostics->report(Diagnostics::PP_MACRO_DUPLICATE_PARAMETER_NAMES, token->location, token->text); return; } - macro.parameters.push_back(token->text); + macro->parameters.push_back(token->text); mTokenizer->lex(token); // Get ','. - } - while (token->type == ','); + } while (token->type == ','); if (token->type != ')') { - mDiagnostics->report(Diagnostics::PP_UNEXPECTED_TOKEN, - token->location, - token->text); + mDiagnostics->report(Diagnostics::PP_UNEXPECTED_TOKEN, token->location, token->text); return; } mTokenizer->lex(token); // Get ')'. @@ -344,47 +404,51 @@ void DirectiveParser::parseDefine(Token *token) // list. Resetting it also allows us to reuse Token::equals() to // compare macros. token->location = SourceLocation(); - macro.replacements.push_back(*token); + macro->replacements.push_back(*token); mTokenizer->lex(token); } - if (!macro.replacements.empty()) + if (!macro->replacements.empty()) { // Whitespace preceding the replacement list is not considered part of // the replacement list for either form of macro. - macro.replacements.front().setHasLeadingSpace(false); + macro->replacements.front().setHasLeadingSpace(false); } // Check for macro redefinition. - MacroSet::const_iterator iter = mMacroSet->find(macro.name); - if (iter != mMacroSet->end() && !macro.equals(iter->second)) + MacroSet::const_iterator iter = mMacroSet->find(macro->name); + if (iter != mMacroSet->end() && !macro->equals(*iter->second)) { - mDiagnostics->report(Diagnostics::PP_MACRO_REDEFINED, - token->location, - macro.name); + mDiagnostics->report(Diagnostics::PP_MACRO_REDEFINED, token->location, macro->name); return; } - mMacroSet->insert(std::make_pair(macro.name, macro)); + mMacroSet->insert(std::make_pair(macro->name, macro)); } void DirectiveParser::parseUndef(Token *token) { - assert(getDirective(token) == DIRECTIVE_UNDEF); + ASSERT(getDirective(token) == DIRECTIVE_UNDEF); mTokenizer->lex(token); if (token->type != Token::IDENTIFIER) { - mDiagnostics->report(Diagnostics::PP_UNEXPECTED_TOKEN, - token->location, token->text); + mDiagnostics->report(Diagnostics::PP_UNEXPECTED_TOKEN, token->location, token->text); return; } MacroSet::iterator iter = mMacroSet->find(token->text); if (iter != mMacroSet->end()) { - if (iter->second.predefined) + if (iter->second->predefined) { - mDiagnostics->report(Diagnostics::PP_MACRO_PREDEFINED_UNDEFINED, - token->location, token->text); + mDiagnostics->report(Diagnostics::PP_MACRO_PREDEFINED_UNDEFINED, token->location, + token->text); + return; + } + else if (iter->second->expansionCount > 0) + { + mDiagnostics->report(Diagnostics::PP_MACRO_UNDEFINED_WHILE_INVOKED, token->location, + token->text); + return; } else { @@ -395,38 +459,37 @@ void DirectiveParser::parseUndef(Token *token) mTokenizer->lex(token); if (!isEOD(token)) { - mDiagnostics->report(Diagnostics::PP_UNEXPECTED_TOKEN, - token->location, token->text); + mDiagnostics->report(Diagnostics::PP_UNEXPECTED_TOKEN, token->location, token->text); skipUntilEOD(mTokenizer, token); } } void DirectiveParser::parseIf(Token *token) { - assert(getDirective(token) == DIRECTIVE_IF); + ASSERT(getDirective(token) == DIRECTIVE_IF); parseConditionalIf(token); } void DirectiveParser::parseIfdef(Token *token) { - assert(getDirective(token) == DIRECTIVE_IFDEF); + ASSERT(getDirective(token) == DIRECTIVE_IFDEF); parseConditionalIf(token); } void DirectiveParser::parseIfndef(Token *token) { - assert(getDirective(token) == DIRECTIVE_IFNDEF); + ASSERT(getDirective(token) == DIRECTIVE_IFNDEF); parseConditionalIf(token); } void DirectiveParser::parseElse(Token *token) { - assert(getDirective(token) == DIRECTIVE_ELSE); + ASSERT(getDirective(token) == DIRECTIVE_ELSE); if (mConditionalStack.empty()) { - mDiagnostics->report(Diagnostics::PP_CONDITIONAL_ELSE_WITHOUT_IF, - token->location, token->text); + mDiagnostics->report(Diagnostics::PP_CONDITIONAL_ELSE_WITHOUT_IF, token->location, + token->text); skipUntilEOD(mTokenizer, token); return; } @@ -440,34 +503,34 @@ void DirectiveParser::parseElse(Token *token) } if (block.foundElseGroup) { - mDiagnostics->report(Diagnostics::PP_CONDITIONAL_ELSE_AFTER_ELSE, - token->location, token->text); + mDiagnostics->report(Diagnostics::PP_CONDITIONAL_ELSE_AFTER_ELSE, token->location, + token->text); skipUntilEOD(mTokenizer, token); return; } - block.foundElseGroup = true; - block.skipGroup = block.foundValidGroup; + block.foundElseGroup = true; + block.skipGroup = block.foundValidGroup; block.foundValidGroup = true; // Check if there are extra tokens after #else. mTokenizer->lex(token); if (!isEOD(token)) { - mDiagnostics->report(Diagnostics::PP_CONDITIONAL_UNEXPECTED_TOKEN, - token->location, token->text); + mDiagnostics->report(Diagnostics::PP_CONDITIONAL_UNEXPECTED_TOKEN, token->location, + token->text); skipUntilEOD(mTokenizer, token); } } void DirectiveParser::parseElif(Token *token) { - assert(getDirective(token) == DIRECTIVE_ELIF); + ASSERT(getDirective(token) == DIRECTIVE_ELIF); if (mConditionalStack.empty()) { - mDiagnostics->report(Diagnostics::PP_CONDITIONAL_ELIF_WITHOUT_IF, - token->location, token->text); + mDiagnostics->report(Diagnostics::PP_CONDITIONAL_ELIF_WITHOUT_IF, token->location, + token->text); skipUntilEOD(mTokenizer, token); return; } @@ -481,8 +544,8 @@ void DirectiveParser::parseElif(Token *token) } if (block.foundElseGroup) { - mDiagnostics->report(Diagnostics::PP_CONDITIONAL_ELIF_AFTER_ELSE, - token->location, token->text); + mDiagnostics->report(Diagnostics::PP_CONDITIONAL_ELIF_AFTER_ELSE, token->location, + token->text); skipUntilEOD(mTokenizer, token); return; } @@ -495,19 +558,19 @@ void DirectiveParser::parseElif(Token *token) return; } - int expression = parseExpressionIf(token); - block.skipGroup = expression == 0; + int expression = parseExpressionIf(token); + block.skipGroup = expression == 0; block.foundValidGroup = expression != 0; } void DirectiveParser::parseEndif(Token *token) { - assert(getDirective(token) == DIRECTIVE_ENDIF); + ASSERT(getDirective(token) == DIRECTIVE_ENDIF); if (mConditionalStack.empty()) { - mDiagnostics->report(Diagnostics::PP_CONDITIONAL_ENDIF_WITHOUT_IF, - token->location, token->text); + mDiagnostics->report(Diagnostics::PP_CONDITIONAL_ENDIF_WITHOUT_IF, token->location, + token->text); skipUntilEOD(mTokenizer, token); return; } @@ -518,15 +581,15 @@ void DirectiveParser::parseEndif(Token *token) mTokenizer->lex(token); if (!isEOD(token)) { - mDiagnostics->report(Diagnostics::PP_CONDITIONAL_UNEXPECTED_TOKEN, - token->location, token->text); + mDiagnostics->report(Diagnostics::PP_CONDITIONAL_UNEXPECTED_TOKEN, token->location, + token->text); skipUntilEOD(mTokenizer, token); } } void DirectiveParser::parseError(Token *token) { - assert(getDirective(token) == DIRECTIVE_ERROR); + ASSERT(getDirective(token) == DIRECTIVE_ERROR); std::ostringstream stream; mTokenizer->lex(token); @@ -541,7 +604,7 @@ void DirectiveParser::parseError(Token *token) // Parses pragma of form: #pragma name[(value)]. void DirectiveParser::parsePragma(Token *token) { - assert(getDirective(token) == DIRECTIVE_PRAGMA); + ASSERT(getDirective(token) == DIRECTIVE_PRAGMA); enum State { @@ -563,25 +626,25 @@ void DirectiveParser::parsePragma(Token *token) } while ((token->type != '\n') && (token->type != Token::LAST)) { - switch(state++) + switch (state++) { - case PRAGMA_NAME: - name = token->text; - valid = valid && (token->type == Token::IDENTIFIER); - break; - case LEFT_PAREN: - valid = valid && (token->type == '('); - break; - case PRAGMA_VALUE: - value = token->text; - valid = valid && (token->type == Token::IDENTIFIER); - break; - case RIGHT_PAREN: - valid = valid && (token->type == ')'); - break; - default: - valid = false; - break; + case PRAGMA_NAME: + name = token->text; + valid = valid && (token->type == Token::IDENTIFIER); + break; + case LEFT_PAREN: + valid = valid && (token->type == '('); + break; + case PRAGMA_VALUE: + value = token->text; + valid = valid && (token->type == Token::IDENTIFIER); + break; + case RIGHT_PAREN: + valid = valid && (token->type == ')'); + break; + default: + valid = false; + break; } mTokenizer->lex(token); } @@ -591,8 +654,7 @@ void DirectiveParser::parsePragma(Token *token) (state == RIGHT_PAREN + 1)); // With value. if (!valid) { - mDiagnostics->report(Diagnostics::PP_UNRECOGNIZED_PRAGMA, - token->location, name); + mDiagnostics->report(Diagnostics::PP_UNRECOGNIZED_PRAGMA, token->location, name); } else if (state > PRAGMA_NAME) // Do not notify for empty pragma. { @@ -602,7 +664,7 @@ void DirectiveParser::parsePragma(Token *token) void DirectiveParser::parseExtension(Token *token) { - assert(getDirective(token) == DIRECTIVE_EXTENSION); + ASSERT(getDirective(token) == DIRECTIVE_EXTENSION); enum State { @@ -620,47 +682,49 @@ void DirectiveParser::parseExtension(Token *token) { switch (state++) { - case EXT_NAME: - if (valid && (token->type != Token::IDENTIFIER)) - { - mDiagnostics->report(Diagnostics::PP_INVALID_EXTENSION_NAME, - token->location, token->text); - valid = false; - } - if (valid) name = token->text; - break; - case COLON: - if (valid && (token->type != ':')) - { - mDiagnostics->report(Diagnostics::PP_UNEXPECTED_TOKEN, - token->location, token->text); - valid = false; - } - break; - case EXT_BEHAVIOR: - if (valid && (token->type != Token::IDENTIFIER)) - { - mDiagnostics->report(Diagnostics::PP_INVALID_EXTENSION_BEHAVIOR, - token->location, token->text); - valid = false; - } - if (valid) behavior = token->text; - break; - default: - if (valid) - { - mDiagnostics->report(Diagnostics::PP_UNEXPECTED_TOKEN, - token->location, token->text); - valid = false; - } - break; + case EXT_NAME: + if (valid && (token->type != Token::IDENTIFIER)) + { + mDiagnostics->report(Diagnostics::PP_INVALID_EXTENSION_NAME, token->location, + token->text); + valid = false; + } + if (valid) + name = token->text; + break; + case COLON: + if (valid && (token->type != ':')) + { + mDiagnostics->report(Diagnostics::PP_UNEXPECTED_TOKEN, token->location, + token->text); + valid = false; + } + break; + case EXT_BEHAVIOR: + if (valid && (token->type != Token::IDENTIFIER)) + { + mDiagnostics->report(Diagnostics::PP_INVALID_EXTENSION_BEHAVIOR, + token->location, token->text); + valid = false; + } + if (valid) + behavior = token->text; + break; + default: + if (valid) + { + mDiagnostics->report(Diagnostics::PP_UNEXPECTED_TOKEN, token->location, + token->text); + valid = false; + } + break; } mTokenizer->lex(token); } if (valid && (state != EXT_BEHAVIOR + 1)) { - mDiagnostics->report(Diagnostics::PP_INVALID_EXTENSION_DIRECTIVE, - token->location, token->text); + mDiagnostics->report(Diagnostics::PP_INVALID_EXTENSION_DIRECTIVE, token->location, + token->text); valid = false; } if (valid && mSeenNonPreprocessorToken) @@ -683,12 +747,12 @@ void DirectiveParser::parseExtension(Token *token) void DirectiveParser::parseVersion(Token *token) { - assert(getDirective(token) == DIRECTIVE_VERSION); + ASSERT(getDirective(token) == DIRECTIVE_VERSION); if (mPastFirstStatement) { - mDiagnostics->report(Diagnostics::PP_VERSION_NOT_FIRST_STATEMENT, - token->location, token->text); + mDiagnostics->report(Diagnostics::PP_VERSION_NOT_FIRST_STATEMENT, token->location, + token->text); skipUntilEOD(mTokenizer, token); return; } @@ -700,47 +764,47 @@ void DirectiveParser::parseVersion(Token *token) VERSION_ENDLINE }; - bool valid = true; + bool valid = true; int version = 0; - int state = VERSION_NUMBER; + int state = VERSION_NUMBER; mTokenizer->lex(token); while (valid && (token->type != '\n') && (token->type != Token::LAST)) { switch (state) { - case VERSION_NUMBER: - if (token->type != Token::CONST_INT) - { - mDiagnostics->report(Diagnostics::PP_INVALID_VERSION_NUMBER, - token->location, token->text); - valid = false; - } - if (valid && !token->iValue(&version)) - { - mDiagnostics->report(Diagnostics::PP_INTEGER_OVERFLOW, - token->location, token->text); - valid = false; - } - if (valid) - { - state = (version < 300) ? VERSION_ENDLINE : VERSION_PROFILE; - } - break; - case VERSION_PROFILE: - if (token->type != Token::IDENTIFIER || token->text != "es") - { - mDiagnostics->report(Diagnostics::PP_INVALID_VERSION_DIRECTIVE, - token->location, token->text); + case VERSION_NUMBER: + if (token->type != Token::CONST_INT) + { + mDiagnostics->report(Diagnostics::PP_INVALID_VERSION_NUMBER, token->location, + token->text); + valid = false; + } + if (valid && !token->iValue(&version)) + { + mDiagnostics->report(Diagnostics::PP_INTEGER_OVERFLOW, token->location, + token->text); + valid = false; + } + if (valid) + { + state = (version < 300) ? VERSION_ENDLINE : VERSION_PROFILE; + } + break; + case VERSION_PROFILE: + if (token->type != Token::IDENTIFIER || token->text != "es") + { + mDiagnostics->report(Diagnostics::PP_INVALID_VERSION_DIRECTIVE, token->location, + token->text); + valid = false; + } + state = VERSION_ENDLINE; + break; + default: + mDiagnostics->report(Diagnostics::PP_UNEXPECTED_TOKEN, token->location, + token->text); valid = false; - } - state = VERSION_ENDLINE; - break; - default: - mDiagnostics->report(Diagnostics::PP_UNEXPECTED_TOKEN, - token->location, token->text); - valid = false; - break; + break; } mTokenizer->lex(token); @@ -748,15 +812,15 @@ void DirectiveParser::parseVersion(Token *token) if (valid && (state != VERSION_ENDLINE)) { - mDiagnostics->report(Diagnostics::PP_INVALID_VERSION_DIRECTIVE, - token->location, token->text); + mDiagnostics->report(Diagnostics::PP_INVALID_VERSION_DIRECTIVE, token->location, + token->text); valid = false; } if (valid && version >= 300 && token->location.line > 1) { - mDiagnostics->report(Diagnostics::PP_VERSION_NOT_FIRST_LINE_ESSL3, - token->location, token->text); + mDiagnostics->report(Diagnostics::PP_VERSION_NOT_FIRST_LINE_ESSL3, token->location, + token->text); valid = false; } @@ -770,13 +834,13 @@ void DirectiveParser::parseVersion(Token *token) void DirectiveParser::parseLine(Token *token) { - assert(getDirective(token) == DIRECTIVE_LINE); + ASSERT(getDirective(token) == DIRECTIVE_LINE); - bool valid = true; + bool valid = true; bool parsedFileNumber = false; int line = 0, file = 0; - MacroExpander macroExpander(mTokenizer, mMacroSet, mDiagnostics, false); + MacroExpander macroExpander(mTokenizer, mMacroSet, mDiagnostics, mMaxMacroExpansionDepth); // Lex the first token after "#line" so we can check it for EOD. macroExpander.lex(token); @@ -814,8 +878,8 @@ void DirectiveParser::parseLine(Token *token) { if (valid) { - mDiagnostics->report(Diagnostics::PP_UNEXPECTED_TOKEN, - token->location, token->text); + mDiagnostics->report(Diagnostics::PP_UNEXPECTED_TOKEN, token->location, + token->text); valid = false; } skipUntilEOD(mTokenizer, token); @@ -835,14 +899,14 @@ bool DirectiveParser::skipping() const if (mConditionalStack.empty()) return false; - const ConditionalBlock& block = mConditionalStack.back(); + const ConditionalBlock &block = mConditionalStack.back(); return block.skipBlock || block.skipGroup; } void DirectiveParser::parseConditionalIf(Token *token) { ConditionalBlock block; - block.type = token->text; + block.type = token->text; block.location = token->location; if (skipping()) @@ -861,20 +925,20 @@ void DirectiveParser::parseConditionalIf(Token *token) int expression = 0; switch (directive) { - case DIRECTIVE_IF: - expression = parseExpressionIf(token); - break; - case DIRECTIVE_IFDEF: - expression = parseExpressionIfdef(token); - break; - case DIRECTIVE_IFNDEF: - expression = parseExpressionIfdef(token) == 0 ? 1 : 0; - break; - default: - assert(false); - break; + case DIRECTIVE_IF: + expression = parseExpressionIf(token); + break; + case DIRECTIVE_IFDEF: + expression = parseExpressionIfdef(token); + break; + case DIRECTIVE_IFNDEF: + expression = parseExpressionIfdef(token) == 0 ? 1 : 0; + break; + default: + UNREACHABLE(); + break; } - block.skipGroup = expression == 0; + block.skipGroup = expression == 0; block.foundValidGroup = expression != 0; } mConditionalStack.push_back(block); @@ -882,16 +946,16 @@ void DirectiveParser::parseConditionalIf(Token *token) int DirectiveParser::parseExpressionIf(Token *token) { - assert((getDirective(token) == DIRECTIVE_IF) || - (getDirective(token) == DIRECTIVE_ELIF)); + ASSERT((getDirective(token) == DIRECTIVE_IF) || (getDirective(token) == DIRECTIVE_ELIF)); - MacroExpander macroExpander(mTokenizer, mMacroSet, mDiagnostics, true); + DefinedParser definedParser(mTokenizer, mMacroSet, mDiagnostics); + MacroExpander macroExpander(&definedParser, mMacroSet, mDiagnostics, mMaxMacroExpansionDepth); ExpressionParser expressionParser(¯oExpander, mDiagnostics); int expression = 0; ExpressionParser::ErrorSettings errorSettings; errorSettings.integerLiteralsMustFit32BitSignedRange = false; - errorSettings.unexpectedIdentifier = Diagnostics::PP_CONDITIONAL_UNEXPECTED_TOKEN; + errorSettings.unexpectedIdentifier = Diagnostics::PP_CONDITIONAL_UNEXPECTED_TOKEN; bool valid = true; expressionParser.parse(token, &expression, false, errorSettings, &valid); @@ -899,8 +963,8 @@ int DirectiveParser::parseExpressionIf(Token *token) // Check if there are tokens after #if expression. if (!isEOD(token)) { - mDiagnostics->report(Diagnostics::PP_CONDITIONAL_UNEXPECTED_TOKEN, - token->location, token->text); + mDiagnostics->report(Diagnostics::PP_CONDITIONAL_UNEXPECTED_TOKEN, token->location, + token->text); skipUntilEOD(mTokenizer, token); } @@ -909,27 +973,25 @@ int DirectiveParser::parseExpressionIf(Token *token) int DirectiveParser::parseExpressionIfdef(Token *token) { - assert((getDirective(token) == DIRECTIVE_IFDEF) || - (getDirective(token) == DIRECTIVE_IFNDEF)); + ASSERT((getDirective(token) == DIRECTIVE_IFDEF) || (getDirective(token) == DIRECTIVE_IFNDEF)); mTokenizer->lex(token); if (token->type != Token::IDENTIFIER) { - mDiagnostics->report(Diagnostics::PP_UNEXPECTED_TOKEN, - token->location, token->text); + mDiagnostics->report(Diagnostics::PP_UNEXPECTED_TOKEN, token->location, token->text); skipUntilEOD(mTokenizer, token); return 0; } MacroSet::const_iterator iter = mMacroSet->find(token->text); - int expression = iter != mMacroSet->end() ? 1 : 0; + int expression = iter != mMacroSet->end() ? 1 : 0; // Check if there are tokens after #ifdef expression. mTokenizer->lex(token); if (!isEOD(token)) { - mDiagnostics->report(Diagnostics::PP_CONDITIONAL_UNEXPECTED_TOKEN, - token->location, token->text); + mDiagnostics->report(Diagnostics::PP_CONDITIONAL_UNEXPECTED_TOKEN, token->location, + token->text); skipUntilEOD(mTokenizer, token); } return expression; |