diff options
Diffstat (limited to 'src/3rdparty/angle/src/compiler/preprocessor')
24 files changed, 0 insertions, 3673 deletions
diff --git a/src/3rdparty/angle/src/compiler/preprocessor/DiagnosticsBase.cpp b/src/3rdparty/angle/src/compiler/preprocessor/DiagnosticsBase.cpp deleted file mode 100644 index c89bc9fa76..0000000000 --- a/src/3rdparty/angle/src/compiler/preprocessor/DiagnosticsBase.cpp +++ /dev/null @@ -1,143 +0,0 @@ -// -// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// - -#include "compiler/preprocessor/DiagnosticsBase.h" - -#include "common/debug.h" - -namespace pp -{ - -Diagnostics::~Diagnostics() -{ -} - -void Diagnostics::report(ID id, const SourceLocation &loc, const std::string &text) -{ - print(id, loc, text); -} - -bool Diagnostics::isError(ID id) -{ - if ((id > PP_ERROR_BEGIN) && (id < PP_ERROR_END)) - return true; - - if ((id > PP_WARNING_BEGIN) && (id < PP_WARNING_END)) - return false; - - UNREACHABLE(); - return true; -} - -const char *Diagnostics::message(ID id) -{ - switch (id) - { - // Errors begin. - case PP_INTERNAL_ERROR: - return "internal error"; - case PP_OUT_OF_MEMORY: - return "out of memory"; - case PP_INVALID_CHARACTER: - return "invalid character"; - case PP_INVALID_NUMBER: - return "invalid number"; - case PP_INTEGER_OVERFLOW: - return "integer overflow"; - case PP_FLOAT_OVERFLOW: - return "float overflow"; - case PP_TOKEN_TOO_LONG: - return "token too long"; - case PP_INVALID_EXPRESSION: - return "invalid expression"; - case PP_DIVISION_BY_ZERO: - return "division by zero"; - case PP_EOF_IN_COMMENT: - return "unexpected end of file found in comment"; - case PP_UNEXPECTED_TOKEN: - return "unexpected token"; - case PP_DIRECTIVE_INVALID_NAME: - return "invalid directive name"; - case PP_MACRO_NAME_RESERVED: - return "macro name is reserved"; - case PP_MACRO_REDEFINED: - return "macro redefined"; - case PP_MACRO_PREDEFINED_REDEFINED: - return "predefined macro redefined"; - case PP_MACRO_PREDEFINED_UNDEFINED: - return "predefined macro undefined"; - case PP_MACRO_UNTERMINATED_INVOCATION: - return "unterminated macro invocation"; - case PP_MACRO_UNDEFINED_WHILE_INVOKED: - return "macro undefined while being invoked"; - case PP_MACRO_TOO_FEW_ARGS: - return "Not enough arguments for macro"; - case PP_MACRO_TOO_MANY_ARGS: - return "Too many arguments for macro"; - case PP_MACRO_DUPLICATE_PARAMETER_NAMES: - return "duplicate macro parameter name"; - case PP_MACRO_INVOCATION_CHAIN_TOO_DEEP: - return "macro invocation chain too deep"; - case PP_CONDITIONAL_ENDIF_WITHOUT_IF: - return "unexpected #endif found without a matching #if"; - case PP_CONDITIONAL_ELSE_WITHOUT_IF: - return "unexpected #else found without a matching #if"; - case PP_CONDITIONAL_ELSE_AFTER_ELSE: - return "unexpected #else found after another #else"; - case PP_CONDITIONAL_ELIF_WITHOUT_IF: - return "unexpected #elif found without a matching #if"; - case PP_CONDITIONAL_ELIF_AFTER_ELSE: - return "unexpected #elif found after #else"; - case PP_CONDITIONAL_UNTERMINATED: - return "unexpected end of file found in conditional block"; - case PP_INVALID_EXTENSION_NAME: - return "invalid extension name"; - case PP_INVALID_EXTENSION_BEHAVIOR: - return "invalid extension behavior"; - case PP_INVALID_EXTENSION_DIRECTIVE: - return "invalid extension directive"; - case PP_INVALID_VERSION_NUMBER: - return "invalid version number"; - case PP_INVALID_VERSION_DIRECTIVE: - return "invalid version directive"; - case PP_VERSION_NOT_FIRST_STATEMENT: - return "#version directive must occur before anything else, " - "except for comments and white space"; - case PP_VERSION_NOT_FIRST_LINE_ESSL3: - return "#version directive must occur on the first line of the shader"; - case PP_INVALID_LINE_NUMBER: - return "invalid line number"; - case PP_INVALID_FILE_NUMBER: - return "invalid file number"; - case PP_INVALID_LINE_DIRECTIVE: - return "invalid line directive"; - case PP_NON_PP_TOKEN_BEFORE_EXTENSION_ESSL3: - return "extension directive must occur before any non-preprocessor tokens in ESSL3"; - case PP_UNDEFINED_SHIFT: - return "shift exponent is negative or undefined"; - case PP_TOKENIZER_ERROR: - return "internal tokenizer error"; - // Errors end. - // Warnings begin. - case PP_EOF_IN_DIRECTIVE: - return "unexpected end of file found in directive"; - case PP_CONDITIONAL_UNEXPECTED_TOKEN: - return "unexpected token after conditional expression"; - case PP_UNRECOGNIZED_PRAGMA: - return "unrecognized pragma"; - case PP_NON_PP_TOKEN_BEFORE_EXTENSION_ESSL1: - return "extension directive should occur before any non-preprocessor tokens"; - case PP_WARNING_MACRO_NAME_RESERVED: - return "macro name with a double underscore is reserved - unintented behavior is " - "possible"; - // Warnings end. - default: - UNREACHABLE(); - return ""; - } -} - -} // namespace pp diff --git a/src/3rdparty/angle/src/compiler/preprocessor/DiagnosticsBase.h b/src/3rdparty/angle/src/compiler/preprocessor/DiagnosticsBase.h deleted file mode 100644 index ea37614606..0000000000 --- a/src/3rdparty/angle/src/compiler/preprocessor/DiagnosticsBase.h +++ /dev/null @@ -1,90 +0,0 @@ -// -// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// - -#ifndef COMPILER_PREPROCESSOR_DIAGNOSTICSBASE_H_ -#define COMPILER_PREPROCESSOR_DIAGNOSTICSBASE_H_ - -#include <string> - -namespace pp -{ - -struct SourceLocation; - -// Base class for reporting diagnostic messages. -// Derived classes are responsible for formatting and printing the messages. -class Diagnostics -{ - public: - enum ID - { - PP_ERROR_BEGIN, - PP_INTERNAL_ERROR, - PP_OUT_OF_MEMORY, - PP_INVALID_CHARACTER, - PP_INVALID_NUMBER, - PP_INTEGER_OVERFLOW, - PP_FLOAT_OVERFLOW, - PP_TOKEN_TOO_LONG, - PP_INVALID_EXPRESSION, - PP_DIVISION_BY_ZERO, - PP_EOF_IN_COMMENT, - PP_UNEXPECTED_TOKEN, - PP_DIRECTIVE_INVALID_NAME, - PP_MACRO_NAME_RESERVED, - PP_MACRO_REDEFINED, - PP_MACRO_PREDEFINED_REDEFINED, - PP_MACRO_PREDEFINED_UNDEFINED, - PP_MACRO_UNTERMINATED_INVOCATION, - PP_MACRO_UNDEFINED_WHILE_INVOKED, - PP_MACRO_TOO_FEW_ARGS, - PP_MACRO_TOO_MANY_ARGS, - PP_MACRO_DUPLICATE_PARAMETER_NAMES, - PP_MACRO_INVOCATION_CHAIN_TOO_DEEP, - PP_CONDITIONAL_ENDIF_WITHOUT_IF, - PP_CONDITIONAL_ELSE_WITHOUT_IF, - PP_CONDITIONAL_ELSE_AFTER_ELSE, - PP_CONDITIONAL_ELIF_WITHOUT_IF, - PP_CONDITIONAL_ELIF_AFTER_ELSE, - PP_CONDITIONAL_UNTERMINATED, - PP_CONDITIONAL_UNEXPECTED_TOKEN, - PP_INVALID_EXTENSION_NAME, - PP_INVALID_EXTENSION_BEHAVIOR, - PP_INVALID_EXTENSION_DIRECTIVE, - PP_INVALID_VERSION_NUMBER, - PP_INVALID_VERSION_DIRECTIVE, - PP_VERSION_NOT_FIRST_STATEMENT, - PP_VERSION_NOT_FIRST_LINE_ESSL3, - PP_INVALID_LINE_NUMBER, - PP_INVALID_FILE_NUMBER, - PP_INVALID_LINE_DIRECTIVE, - PP_NON_PP_TOKEN_BEFORE_EXTENSION_ESSL3, - PP_UNDEFINED_SHIFT, - PP_TOKENIZER_ERROR, - PP_ERROR_END, - - PP_WARNING_BEGIN, - PP_EOF_IN_DIRECTIVE, - PP_UNRECOGNIZED_PRAGMA, - PP_NON_PP_TOKEN_BEFORE_EXTENSION_ESSL1, - PP_WARNING_MACRO_NAME_RESERVED, - PP_WARNING_END - }; - - virtual ~Diagnostics(); - - void report(ID id, const SourceLocation &loc, const std::string &text); - - protected: - bool isError(ID id); - const char *message(ID id); - - virtual void print(ID id, const SourceLocation &loc, const std::string &text) = 0; -}; - -} // namespace pp - -#endif // COMPILER_PREPROCESSOR_DIAGNOSTICSBASE_H_ diff --git a/src/3rdparty/angle/src/compiler/preprocessor/DirectiveHandlerBase.cpp b/src/3rdparty/angle/src/compiler/preprocessor/DirectiveHandlerBase.cpp deleted file mode 100644 index 049dae9071..0000000000 --- a/src/3rdparty/angle/src/compiler/preprocessor/DirectiveHandlerBase.cpp +++ /dev/null @@ -1,16 +0,0 @@ -// -// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// - -#include "compiler/preprocessor/DirectiveHandlerBase.h" - -namespace pp -{ - -DirectiveHandler::~DirectiveHandler() -{ -} - -} // namespace pp diff --git a/src/3rdparty/angle/src/compiler/preprocessor/DirectiveHandlerBase.h b/src/3rdparty/angle/src/compiler/preprocessor/DirectiveHandlerBase.h deleted file mode 100644 index 6c81d015f5..0000000000 --- a/src/3rdparty/angle/src/compiler/preprocessor/DirectiveHandlerBase.h +++ /dev/null @@ -1,43 +0,0 @@ -// -// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// - -#ifndef COMPILER_PREPROCESSOR_DIRECTIVEHANDLERBASE_H_ -#define COMPILER_PREPROCESSOR_DIRECTIVEHANDLERBASE_H_ - -#include <string> - -namespace pp -{ - -struct SourceLocation; - -// Base class for handling directives. -// Preprocessor uses this class to notify the clients about certain -// preprocessor directives. Derived classes are responsible for -// handling them in an appropriate manner. -class DirectiveHandler -{ - public: - virtual ~DirectiveHandler(); - - virtual void handleError(const SourceLocation &loc, const std::string &msg) = 0; - - // Handle pragma of form: #pragma name[(value)] - virtual void handlePragma(const SourceLocation &loc, - const std::string &name, - const std::string &value, - bool stdgl) = 0; - - virtual void handleExtension(const SourceLocation &loc, - const std::string &name, - const std::string &behavior) = 0; - - virtual void handleVersion(const SourceLocation &loc, int version) = 0; -}; - -} // namespace pp - -#endif // COMPILER_PREPROCESSOR_DIRECTIVEHANDLERBASE_H_ diff --git a/src/3rdparty/angle/src/compiler/preprocessor/DirectiveParser.cpp b/src/3rdparty/angle/src/compiler/preprocessor/DirectiveParser.cpp deleted file mode 100644 index f6c5763990..0000000000 --- a/src/3rdparty/angle/src/compiler/preprocessor/DirectiveParser.cpp +++ /dev/null @@ -1,1000 +0,0 @@ -// -// Copyright (c) 2011-2013 The ANGLE Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// - -#include "compiler/preprocessor/DirectiveParser.h" - -#include <algorithm> -#include <cstdlib> -#include <sstream> - -#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 -{ -enum DirectiveType -{ - DIRECTIVE_NONE, - DIRECTIVE_DEFINE, - DIRECTIVE_UNDEF, - DIRECTIVE_IF, - DIRECTIVE_IFDEF, - DIRECTIVE_IFNDEF, - DIRECTIVE_ELSE, - DIRECTIVE_ELIF, - DIRECTIVE_ENDIF, - DIRECTIVE_ERROR, - DIRECTIVE_PRAGMA, - DIRECTIVE_EXTENSION, - DIRECTIVE_VERSION, - DIRECTIVE_LINE -}; - -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 kDirectiveExtension[] = "extension"; - const char kDirectiveVersion[] = "version"; - const char kDirectiveLine[] = "line"; - - if (token->type != pp::Token::IDENTIFIER) - return DIRECTIVE_NONE; - - if (token->text == kDirectiveDefine) - return DIRECTIVE_DEFINE; - if (token->text == kDirectiveUndef) - return DIRECTIVE_UNDEF; - if (token->text == kDirectiveIf) - return DIRECTIVE_IF; - if (token->text == kDirectiveIfdef) - return DIRECTIVE_IFDEF; - if (token->text == kDirectiveIfndef) - return DIRECTIVE_IFNDEF; - if (token->text == kDirectiveElse) - return DIRECTIVE_ELSE; - if (token->text == kDirectiveElif) - return DIRECTIVE_ELIF; - if (token->text == kDirectiveEndif) - return DIRECTIVE_ENDIF; - if (token->text == kDirectiveError) - return DIRECTIVE_ERROR; - if (token->text == kDirectivePragma) - return DIRECTIVE_PRAGMA; - if (token->text == kDirectiveExtension) - return DIRECTIVE_EXTENSION; - if (token->text == kDirectiveVersion) - return DIRECTIVE_VERSION; - if (token->text == kDirectiveLine) - return DIRECTIVE_LINE; - - return DIRECTIVE_NONE; -} - -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; - } -} - -// Returns true if the token represents End Of Directive. -bool isEOD(const pp::Token *token) -{ - return (token->type == '\n') || (token->type == pp::Token::LAST); -} - -void skipUntilEOD(pp::Lexer *lexer, pp::Token *token) -{ - while (!isEOD(token)) - { - lexer->lex(token); - } -} - -bool isMacroNameReserved(const std::string &name) -{ - // Names prefixed with "GL_" and the name "defined" are reserved. - return name == "defined" || (name.substr(0, 3) == "GL_"); -} - -bool hasDoubleUnderscores(const std::string &name) -{ - return (name.find("__") != std::string::npos); -} - -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; -} - -} // namespace anonymous - -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, - int maxMacroExpansionDepth) - : mPastFirstStatement(false), - mSeenNonPreprocessorToken(false), - mTokenizer(tokenizer), - mMacroSet(macroSet), - mDiagnostics(diagnostics), - mDirectiveHandler(directiveHandler), - mShaderVersion(100), - mMaxMacroExpansionDepth(maxMacroExpansionDepth) -{ -} - -DirectiveParser::~DirectiveParser() -{ -} - -void DirectiveParser::lex(Token *token) -{ - do - { - mTokenizer->lex(token); - - if (token->type == Token::PP_HASH) - { - parseDirective(token); - mPastFirstStatement = true; - } - else if (!isEOD(token)) - { - mSeenNonPreprocessorToken = true; - } - - if (token->type == Token::LAST) - { - if (!mConditionalStack.empty()) - { - const ConditionalBlock &block = mConditionalStack.back(); - mDiagnostics->report(Diagnostics::PP_CONDITIONAL_UNTERMINATED, block.location, - block.type); - } - break; - } - - } while (skipping() || (token->type == '\n')); - - mPastFirstStatement = true; -} - -void DirectiveParser::parseDirective(Token *token) -{ - ASSERT(token->type == Token::PP_HASH); - - mTokenizer->lex(token); - if (isEOD(token)) - { - // Empty Directive. - return; - } - - DirectiveType directive = getDirective(token); - - // While in an excluded conditional block/group, - // we only parse conditional directives. - if (skipping() && !isConditionalDirective(directive)) - { - skipUntilEOD(mTokenizer, token); - return; - } - - 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: - UNREACHABLE(); - break; - } - - skipUntilEOD(mTokenizer, token); - if (token->type == Token::LAST) - { - mDiagnostics->report(Diagnostics::PP_EOF_IN_DIRECTIVE, token->location, token->text); - } -} - -void DirectiveParser::parseDefine(Token *token) -{ - ASSERT(getDirective(token) == DIRECTIVE_DEFINE); - - mTokenizer->lex(token); - if (token->type != Token::IDENTIFIER) - { - 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); - return; - } - if (isMacroNameReserved(token->text)) - { - mDiagnostics->report(Diagnostics::PP_MACRO_NAME_RESERVED, token->location, token->text); - return; - } - // Using double underscores is allowed, but may result in unintended - // behavior, so a warning is issued. At the time of writing this was - // specified in ESSL 3.10, but the intent judging from Khronos - // discussions and dEQP tests was that double underscores should be - // allowed in earlier ESSL versions too. - if (hasDoubleUnderscores(token->text)) - { - mDiagnostics->report(Diagnostics::PP_WARNING_MACRO_NAME_RESERVED, token->location, - 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; - do - { - mTokenizer->lex(token); - if (token->type != Token::IDENTIFIER) - break; - - 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); - - mTokenizer->lex(token); // Get ','. - } while (token->type == ','); - - if (token->type != ')') - { - mDiagnostics->report(Diagnostics::PP_UNEXPECTED_TOKEN, token->location, token->text); - return; - } - mTokenizer->lex(token); // Get ')'. - } - - while ((token->type != '\n') && (token->type != Token::LAST)) - { - // Reset the token location because it is unnecessary in replacement - // list. Resetting it also allows us to reuse Token::equals() to - // compare macros. - token->location = SourceLocation(); - macro->replacements.push_back(*token); - mTokenizer->lex(token); - } - 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); - } - - // Check for macro redefinition. - 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); - return; - } - mMacroSet->insert(std::make_pair(macro->name, macro)); -} - -void DirectiveParser::parseUndef(Token *token) -{ - ASSERT(getDirective(token) == DIRECTIVE_UNDEF); - - mTokenizer->lex(token); - if (token->type != Token::IDENTIFIER) - { - 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) - { - 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 - { - mMacroSet->erase(iter); - } - } - - mTokenizer->lex(token); - if (!isEOD(token)) - { - mDiagnostics->report(Diagnostics::PP_UNEXPECTED_TOKEN, token->location, token->text); - skipUntilEOD(mTokenizer, token); - } -} - -void DirectiveParser::parseIf(Token *token) -{ - ASSERT(getDirective(token) == DIRECTIVE_IF); - parseConditionalIf(token); -} - -void DirectiveParser::parseIfdef(Token *token) -{ - ASSERT(getDirective(token) == DIRECTIVE_IFDEF); - parseConditionalIf(token); -} - -void DirectiveParser::parseIfndef(Token *token) -{ - ASSERT(getDirective(token) == DIRECTIVE_IFNDEF); - parseConditionalIf(token); -} - -void DirectiveParser::parseElse(Token *token) -{ - ASSERT(getDirective(token) == DIRECTIVE_ELSE); - - if (mConditionalStack.empty()) - { - mDiagnostics->report(Diagnostics::PP_CONDITIONAL_ELSE_WITHOUT_IF, token->location, - token->text); - skipUntilEOD(mTokenizer, token); - return; - } - - ConditionalBlock &block = mConditionalStack.back(); - if (block.skipBlock) - { - // No diagnostics. Just skip the whole line. - skipUntilEOD(mTokenizer, token); - return; - } - if (block.foundElseGroup) - { - mDiagnostics->report(Diagnostics::PP_CONDITIONAL_ELSE_AFTER_ELSE, token->location, - token->text); - skipUntilEOD(mTokenizer, token); - return; - } - - 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); - skipUntilEOD(mTokenizer, token); - } -} - -void DirectiveParser::parseElif(Token *token) -{ - ASSERT(getDirective(token) == DIRECTIVE_ELIF); - - if (mConditionalStack.empty()) - { - mDiagnostics->report(Diagnostics::PP_CONDITIONAL_ELIF_WITHOUT_IF, token->location, - token->text); - skipUntilEOD(mTokenizer, token); - return; - } - - ConditionalBlock &block = mConditionalStack.back(); - if (block.skipBlock) - { - // No diagnostics. Just skip the whole line. - skipUntilEOD(mTokenizer, token); - return; - } - if (block.foundElseGroup) - { - mDiagnostics->report(Diagnostics::PP_CONDITIONAL_ELIF_AFTER_ELSE, token->location, - token->text); - skipUntilEOD(mTokenizer, token); - return; - } - if (block.foundValidGroup) - { - // Do not parse the expression. - // Also be careful not to emit a diagnostic. - block.skipGroup = true; - skipUntilEOD(mTokenizer, token); - return; - } - - int expression = parseExpressionIf(token); - block.skipGroup = expression == 0; - block.foundValidGroup = expression != 0; -} - -void DirectiveParser::parseEndif(Token *token) -{ - ASSERT(getDirective(token) == DIRECTIVE_ENDIF); - - if (mConditionalStack.empty()) - { - mDiagnostics->report(Diagnostics::PP_CONDITIONAL_ENDIF_WITHOUT_IF, token->location, - token->text); - skipUntilEOD(mTokenizer, token); - return; - } - - mConditionalStack.pop_back(); - - // Check if there are tokens after #endif. - mTokenizer->lex(token); - if (!isEOD(token)) - { - mDiagnostics->report(Diagnostics::PP_CONDITIONAL_UNEXPECTED_TOKEN, token->location, - token->text); - skipUntilEOD(mTokenizer, token); - } -} - -void DirectiveParser::parseError(Token *token) -{ - ASSERT(getDirective(token) == DIRECTIVE_ERROR); - - std::ostringstream stream; - mTokenizer->lex(token); - while ((token->type != '\n') && (token->type != Token::LAST)) - { - stream << *token; - mTokenizer->lex(token); - } - mDirectiveHandler->handleError(token->location, stream.str()); -} - -// Parses pragma of form: #pragma name[(value)]. -void DirectiveParser::parsePragma(Token *token) -{ - ASSERT(getDirective(token) == DIRECTIVE_PRAGMA); - - enum State - { - PRAGMA_NAME, - LEFT_PAREN, - PRAGMA_VALUE, - RIGHT_PAREN - }; - - bool valid = true; - std::string name, value; - int state = PRAGMA_NAME; - - mTokenizer->lex(token); - bool stdgl = token->text == "STDGL"; - if (stdgl) - { - mTokenizer->lex(token); - } - while ((token->type != '\n') && (token->type != Token::LAST)) - { - 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; - } - mTokenizer->lex(token); - } - - valid = valid && ((state == PRAGMA_NAME) || // Empty pragma. - (state == LEFT_PAREN) || // Without value. - (state == RIGHT_PAREN + 1)); // With value. - if (!valid) - { - mDiagnostics->report(Diagnostics::PP_UNRECOGNIZED_PRAGMA, token->location, name); - } - else if (state > PRAGMA_NAME) // Do not notify for empty pragma. - { - mDirectiveHandler->handlePragma(token->location, name, value, stdgl); - } -} - -void DirectiveParser::parseExtension(Token *token) -{ - ASSERT(getDirective(token) == DIRECTIVE_EXTENSION); - - enum State - { - EXT_NAME, - COLON, - EXT_BEHAVIOR - }; - - bool valid = true; - std::string name, behavior; - int state = EXT_NAME; - - mTokenizer->lex(token); - while ((token->type != '\n') && (token->type != Token::LAST)) - { - 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; - } - mTokenizer->lex(token); - } - if (valid && (state != EXT_BEHAVIOR + 1)) - { - mDiagnostics->report(Diagnostics::PP_INVALID_EXTENSION_DIRECTIVE, token->location, - token->text); - valid = false; - } - if (valid && mSeenNonPreprocessorToken) - { - if (mShaderVersion >= 300) - { - mDiagnostics->report(Diagnostics::PP_NON_PP_TOKEN_BEFORE_EXTENSION_ESSL3, - token->location, token->text); - valid = false; - } - else - { - mDiagnostics->report(Diagnostics::PP_NON_PP_TOKEN_BEFORE_EXTENSION_ESSL1, - token->location, token->text); - } - } - if (valid) - mDirectiveHandler->handleExtension(token->location, name, behavior); -} - -void DirectiveParser::parseVersion(Token *token) -{ - ASSERT(getDirective(token) == DIRECTIVE_VERSION); - - if (mPastFirstStatement) - { - mDiagnostics->report(Diagnostics::PP_VERSION_NOT_FIRST_STATEMENT, token->location, - token->text); - skipUntilEOD(mTokenizer, token); - return; - } - - enum State - { - VERSION_NUMBER, - VERSION_PROFILE, - VERSION_ENDLINE - }; - - bool valid = true; - int version = 0; - 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); - valid = false; - } - state = VERSION_ENDLINE; - break; - default: - mDiagnostics->report(Diagnostics::PP_UNEXPECTED_TOKEN, token->location, - token->text); - valid = false; - break; - } - - mTokenizer->lex(token); - } - - if (valid && (state != VERSION_ENDLINE)) - { - 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); - valid = false; - } - - if (valid) - { - mDirectiveHandler->handleVersion(token->location, version); - mShaderVersion = version; - PredefineMacro(mMacroSet, "__VERSION__", version); - } -} - -void DirectiveParser::parseLine(Token *token) -{ - ASSERT(getDirective(token) == DIRECTIVE_LINE); - - bool valid = true; - bool parsedFileNumber = false; - int line = 0, file = 0; - - MacroExpander macroExpander(mTokenizer, mMacroSet, mDiagnostics, mMaxMacroExpansionDepth); - - // Lex the first token after "#line" so we can check it for EOD. - macroExpander.lex(token); - - if (isEOD(token)) - { - mDiagnostics->report(Diagnostics::PP_INVALID_LINE_DIRECTIVE, token->location, token->text); - valid = false; - } - else - { - ExpressionParser expressionParser(¯oExpander, mDiagnostics); - ExpressionParser::ErrorSettings errorSettings; - - // See GLES3 section 12.42 - errorSettings.integerLiteralsMustFit32BitSignedRange = true; - - errorSettings.unexpectedIdentifier = Diagnostics::PP_INVALID_LINE_NUMBER; - // The first token was lexed earlier to check if it was EOD. Include - // the token in parsing for a second time by setting the - // parsePresetToken flag to true. - expressionParser.parse(token, &line, true, errorSettings, &valid); - if (!isEOD(token) && valid) - { - errorSettings.unexpectedIdentifier = Diagnostics::PP_INVALID_FILE_NUMBER; - // After parsing the line expression expressionParser has also - // advanced to the first token of the file expression - this is the - // token that makes the parser reduce the "input" rule for the line - // expression and stop. So we're using parsePresetToken = true here - // as well. - expressionParser.parse(token, &file, true, errorSettings, &valid); - parsedFileNumber = true; - } - if (!isEOD(token)) - { - if (valid) - { - mDiagnostics->report(Diagnostics::PP_UNEXPECTED_TOKEN, token->location, - token->text); - valid = false; - } - skipUntilEOD(mTokenizer, token); - } - } - - if (valid) - { - mTokenizer->setLineNumber(line); - if (parsedFileNumber) - mTokenizer->setFileNumber(file); - } -} - -bool DirectiveParser::skipping() const -{ - if (mConditionalStack.empty()) - return false; - - const ConditionalBlock &block = mConditionalStack.back(); - return block.skipBlock || block.skipGroup; -} - -void DirectiveParser::parseConditionalIf(Token *token) -{ - ConditionalBlock block; - block.type = token->text; - block.location = token->location; - - if (skipping()) - { - // This conditional block is inside another conditional group - // which is skipped. As a consequence this whole block is skipped. - // Be careful not to parse the conditional expression that might - // emit a diagnostic. - skipUntilEOD(mTokenizer, token); - block.skipBlock = true; - } - else - { - DirectiveType directive = getDirective(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: - UNREACHABLE(); - break; - } - block.skipGroup = expression == 0; - block.foundValidGroup = expression != 0; - } - mConditionalStack.push_back(block); -} - -int DirectiveParser::parseExpressionIf(Token *token) -{ - ASSERT((getDirective(token) == DIRECTIVE_IF) || (getDirective(token) == DIRECTIVE_ELIF)); - - 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; - - bool valid = true; - expressionParser.parse(token, &expression, false, errorSettings, &valid); - - // Check if there are tokens after #if expression. - if (!isEOD(token)) - { - mDiagnostics->report(Diagnostics::PP_CONDITIONAL_UNEXPECTED_TOKEN, token->location, - token->text); - skipUntilEOD(mTokenizer, token); - } - - return expression; -} - -int DirectiveParser::parseExpressionIfdef(Token *token) -{ - 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); - skipUntilEOD(mTokenizer, token); - return 0; - } - - MacroSet::const_iterator iter = mMacroSet->find(token->text); - 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); - skipUntilEOD(mTokenizer, token); - } - return expression; -} - -} // namespace pp diff --git a/src/3rdparty/angle/src/compiler/preprocessor/DirectiveParser.h b/src/3rdparty/angle/src/compiler/preprocessor/DirectiveParser.h deleted file mode 100644 index 29c30a8239..0000000000 --- a/src/3rdparty/angle/src/compiler/preprocessor/DirectiveParser.h +++ /dev/null @@ -1,83 +0,0 @@ -// -// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// - -#ifndef COMPILER_PREPROCESSOR_DIRECTIVEPARSER_H_ -#define COMPILER_PREPROCESSOR_DIRECTIVEPARSER_H_ - -#include "compiler/preprocessor/Lexer.h" -#include "compiler/preprocessor/Macro.h" -#include "compiler/preprocessor/SourceLocation.h" - -namespace pp -{ - -class Diagnostics; -class DirectiveHandler; -class Tokenizer; - -class DirectiveParser : public Lexer -{ - public: - DirectiveParser(Tokenizer *tokenizer, - MacroSet *macroSet, - Diagnostics *diagnostics, - DirectiveHandler *directiveHandler, - int maxMacroExpansionDepth); - ~DirectiveParser() override; - - void lex(Token *token) override; - - private: - void parseDirective(Token *token); - void parseDefine(Token *token); - void parseUndef(Token *token); - void parseIf(Token *token); - void parseIfdef(Token *token); - void parseIfndef(Token *token); - void parseElse(Token *token); - void parseElif(Token *token); - void parseEndif(Token *token); - void parseError(Token *token); - void parsePragma(Token *token); - void parseExtension(Token *token); - void parseVersion(Token *token); - void parseLine(Token *token); - - bool skipping() const; - void parseConditionalIf(Token *token); - int parseExpressionIf(Token *token); - int parseExpressionIfdef(Token *token); - - struct ConditionalBlock - { - std::string type; - SourceLocation location; - bool skipBlock; - bool skipGroup; - bool foundValidGroup; - bool foundElseGroup; - - ConditionalBlock() - : skipBlock(false), skipGroup(false), foundValidGroup(false), foundElseGroup(false) - { - } - }; - bool mPastFirstStatement; - bool mSeenNonPreprocessorToken; // Tracks if a non-preprocessor token has been seen yet. Some - // macros, such as - // #extension must be declared before all shader code. - std::vector<ConditionalBlock> mConditionalStack; - Tokenizer *mTokenizer; - MacroSet *mMacroSet; - Diagnostics *mDiagnostics; - DirectiveHandler *mDirectiveHandler; - int mShaderVersion; - int mMaxMacroExpansionDepth; -}; - -} // namespace pp - -#endif // COMPILER_PREPROCESSOR_DIRECTIVEPARSER_H_ diff --git a/src/3rdparty/angle/src/compiler/preprocessor/ExpressionParser.h b/src/3rdparty/angle/src/compiler/preprocessor/ExpressionParser.h deleted file mode 100644 index 0f2901b878..0000000000 --- a/src/3rdparty/angle/src/compiler/preprocessor/ExpressionParser.h +++ /dev/null @@ -1,43 +0,0 @@ -// -// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// - -#ifndef COMPILER_PREPROCESSOR_EXPRESSIONPARSER_H_ -#define COMPILER_PREPROCESSOR_EXPRESSIONPARSER_H_ - -#include "common/angleutils.h" -#include "compiler/preprocessor/DiagnosticsBase.h" - -namespace pp -{ - -class Lexer; -struct Token; - -class ExpressionParser : angle::NonCopyable -{ - public: - struct ErrorSettings - { - Diagnostics::ID unexpectedIdentifier; - bool integerLiteralsMustFit32BitSignedRange; - }; - - ExpressionParser(Lexer *lexer, Diagnostics *diagnostics); - - bool parse(Token *token, - int *result, - bool parsePresetToken, - const ErrorSettings &errorSettings, - bool *valid); - - private: - Lexer *mLexer; - Diagnostics *mDiagnostics; -}; - -} // namespace pp - -#endif // COMPILER_PREPROCESSOR_EXPRESSIONPARSER_H_ diff --git a/src/3rdparty/angle/src/compiler/preprocessor/ExpressionParser.y b/src/3rdparty/angle/src/compiler/preprocessor/ExpressionParser.y deleted file mode 100644 index 68d7cc3958..0000000000 --- a/src/3rdparty/angle/src/compiler/preprocessor/ExpressionParser.y +++ /dev/null @@ -1,462 +0,0 @@ -/* -// -// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// - -This file contains the Yacc grammar for GLSL ES preprocessor expression. - -IF YOU MODIFY THIS FILE YOU ALSO NEED TO RUN generate_parser.sh, -WHICH GENERATES THE GLSL ES preprocessor expression parser. -*/ - -%{ -// -// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// - -// This file is auto-generated by generate_parser.sh. DO NOT EDIT! - -#if defined(__GNUC__) -// Triggered by the auto-generated pplval variable. -#if !defined(__clang__) && ((__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 7)) -#pragma GCC diagnostic ignored "-Wmaybe-uninitialized" -#else -#pragma GCC diagnostic ignored "-Wuninitialized" -#endif -#elif defined(_MSC_VER) -#pragma warning(disable: 4065 4244 4701 4702) -#endif - -#include "ExpressionParser.h" - -#if defined(_MSC_VER) -#include <malloc.h> -#else -#include <stdlib.h> -#endif - -#include <cassert> -#include <sstream> -#include <stdint.h> - -#include "DiagnosticsBase.h" -#include "Lexer.h" -#include "Token.h" -#include "common/mathutil.h" - -typedef int32_t YYSTYPE; -typedef uint32_t UNSIGNED_TYPE; - -#define YYENABLE_NLS 0 -#define YYLTYPE_IS_TRIVIAL 1 -#define YYSTYPE_IS_TRIVIAL 1 -#define YYSTYPE_IS_DECLARED 1 - -namespace { -struct Context -{ - pp::Diagnostics* diagnostics; - pp::Lexer* lexer; - pp::Token* token; - int* result; - bool parsePresetToken; - - pp::ExpressionParser::ErrorSettings errorSettings; - bool *valid; - - void startIgnoreErrors() { ++ignoreErrors; } - void endIgnoreErrors() { --ignoreErrors; } - - bool isIgnoringErrors() { return ignoreErrors > 0; } - - int ignoreErrors; -}; -} // namespace -%} - -%pure-parser -%name-prefix "pp" -%parse-param {Context *context} -%lex-param {Context *context} - -%{ -static int yylex(YYSTYPE* lvalp, Context* context); -static void yyerror(Context* context, const char* reason); -%} - -%token TOK_CONST_INT -%token TOK_IDENTIFIER -%left TOK_OP_OR -%left TOK_OP_AND -%left '|' -%left '^' -%left '&' -%left TOK_OP_EQ TOK_OP_NE -%left '<' '>' TOK_OP_LE TOK_OP_GE -%left TOK_OP_LEFT TOK_OP_RIGHT -%left '+' '-' -%left '*' '/' '%' -%right TOK_UNARY - -%% - -input - : expression { - *(context->result) = static_cast<int>($1); - YYACCEPT; - } -; - -expression - : TOK_CONST_INT - | TOK_IDENTIFIER { - if (!context->isIgnoringErrors()) - { - // This rule should be applied right after the token is lexed, so we can - // refer to context->token in the error message. - context->diagnostics->report(context->errorSettings.unexpectedIdentifier, - context->token->location, context->token->text); - *(context->valid) = false; - } - $$ = $1; - } - | expression TOK_OP_OR { - if ($1 != 0) - { - // Ignore errors in the short-circuited part of the expression. - // ESSL3.00 section 3.4: - // If an operand is not evaluated, the presence of undefined identifiers - // in the operand will not cause an error. - // Unevaluated division by zero should not cause an error either. - context->startIgnoreErrors(); - } - } expression { - if ($1 != 0) - { - context->endIgnoreErrors(); - $$ = static_cast<YYSTYPE>(1); - } - else - { - $$ = $1 || $4; - } - } - | expression TOK_OP_AND { - if ($1 == 0) - { - // Ignore errors in the short-circuited part of the expression. - // ESSL3.00 section 3.4: - // If an operand is not evaluated, the presence of undefined identifiers - // in the operand will not cause an error. - // Unevaluated division by zero should not cause an error either. - context->startIgnoreErrors(); - } - } expression { - if ($1 == 0) - { - context->endIgnoreErrors(); - $$ = static_cast<YYSTYPE>(0); - } - else - { - $$ = $1 && $4; - } - } - | expression '|' expression { - $$ = $1 | $3; - } - | expression '^' expression { - $$ = $1 ^ $3; - } - | expression '&' expression { - $$ = $1 & $3; - } - | expression TOK_OP_NE expression { - $$ = $1 != $3; - } - | expression TOK_OP_EQ expression { - $$ = $1 == $3; - } - | expression TOK_OP_GE expression { - $$ = $1 >= $3; - } - | expression TOK_OP_LE expression { - $$ = $1 <= $3; - } - | expression '>' expression { - $$ = $1 > $3; - } - | expression '<' expression { - $$ = $1 < $3; - } - | expression TOK_OP_RIGHT expression { - if ($3 < 0 || $3 > 31) - { - if (!context->isIgnoringErrors()) - { - std::ostringstream stream; - stream << $1 << " >> " << $3; - std::string text = stream.str(); - context->diagnostics->report(pp::Diagnostics::PP_UNDEFINED_SHIFT, - context->token->location, - text.c_str()); - *(context->valid) = false; - } - $$ = static_cast<YYSTYPE>(0); - } - else if ($1 < 0) - { - // Logical shift right. - $$ = static_cast<YYSTYPE>(static_cast<UNSIGNED_TYPE>($1) >> $3); - } - else - { - $$ = $1 >> $3; - } - } - | expression TOK_OP_LEFT expression { - if ($3 < 0 || $3 > 31) - { - if (!context->isIgnoringErrors()) - { - std::ostringstream stream; - stream << $1 << " << " << $3; - std::string text = stream.str(); - context->diagnostics->report(pp::Diagnostics::PP_UNDEFINED_SHIFT, - context->token->location, - text.c_str()); - *(context->valid) = false; - } - $$ = static_cast<YYSTYPE>(0); - } - else - { - // Logical shift left. Casting to unsigned is needed to ensure there's no signed integer - // overflow, which some tools treat as an error. - $$ = static_cast<YYSTYPE>(static_cast<UNSIGNED_TYPE>($1) << $3); - } - } - | expression '-' expression { - $$ = gl::WrappingDiff<YYSTYPE>($1, $3); - } - | expression '+' expression { - $$ = gl::WrappingSum<YYSTYPE>($1, $3); - } - | expression '%' expression { - if ($3 == 0) - { - if (!context->isIgnoringErrors()) - { - std::ostringstream stream; - stream << $1 << " % " << $3; - std::string text = stream.str(); - context->diagnostics->report(pp::Diagnostics::PP_DIVISION_BY_ZERO, - context->token->location, - text.c_str()); - *(context->valid) = false; - } - $$ = static_cast<YYSTYPE>(0); - } - else if (($1 == std::numeric_limits<YYSTYPE>::min()) && ($3 == -1)) - { - // Check for the special case where the minimum representable number is - // divided by -1. If left alone this has undefined results. - $$ = 0; - } - else - { - $$ = $1 % $3; - } - } - | expression '/' expression { - if ($3 == 0) - { - if (!context->isIgnoringErrors()) - { - std::ostringstream stream; - stream << $1 << " / " << $3; - std::string text = stream.str(); - context->diagnostics->report(pp::Diagnostics::PP_DIVISION_BY_ZERO, - context->token->location, - text.c_str()); - *(context->valid) = false; - } - $$ = static_cast<YYSTYPE>(0); - } - else if (($1 == std::numeric_limits<YYSTYPE>::min()) && ($3 == -1)) - { - // Check for the special case where the minimum representable number is - // divided by -1. If left alone this leads to integer overflow in C++, which - // has undefined results. - $$ = std::numeric_limits<YYSTYPE>::max(); - } - else - { - $$ = $1 / $3; - } - } - | expression '*' expression { - $$ = gl::WrappingMul($1, $3); - } - | '!' expression %prec TOK_UNARY { - $$ = ! $2; - } - | '~' expression %prec TOK_UNARY { - $$ = ~ $2; - } - | '-' expression %prec TOK_UNARY { - // Check for negation of minimum representable integer to prevent undefined signed int - // overflow. - if ($2 == std::numeric_limits<YYSTYPE>::min()) - { - $$ = std::numeric_limits<YYSTYPE>::min(); - } - else - { - $$ = -$2; - } - } - | '+' expression %prec TOK_UNARY { - $$ = + $2; - } - | '(' expression ')' { - $$ = $2; - } -; - -%% - -int yylex(YYSTYPE *lvalp, Context *context) -{ - pp::Token *token = context->token; - if (!context->parsePresetToken) - { - context->lexer->lex(token); - } - context->parsePresetToken = false; - - int type = 0; - - switch (token->type) - { - case pp::Token::CONST_INT: { - unsigned int val = 0; - int testVal = 0; - if (!token->uValue(&val) || (!token->iValue(&testVal) && - context->errorSettings.integerLiteralsMustFit32BitSignedRange)) - { - context->diagnostics->report(pp::Diagnostics::PP_INTEGER_OVERFLOW, - token->location, token->text); - *(context->valid) = false; - } - *lvalp = static_cast<YYSTYPE>(val); - type = TOK_CONST_INT; - break; - } - case pp::Token::IDENTIFIER: - *lvalp = static_cast<YYSTYPE>(-1); - type = TOK_IDENTIFIER; - break; - case pp::Token::OP_OR: - type = TOK_OP_OR; - break; - case pp::Token::OP_AND: - type = TOK_OP_AND; - break; - case pp::Token::OP_NE: - type = TOK_OP_NE; - break; - case pp::Token::OP_EQ: - type = TOK_OP_EQ; - break; - case pp::Token::OP_GE: - type = TOK_OP_GE; - break; - case pp::Token::OP_LE: - type = TOK_OP_LE; - break; - case pp::Token::OP_RIGHT: - type = TOK_OP_RIGHT; - break; - case pp::Token::OP_LEFT: - type = TOK_OP_LEFT; - break; - case '|': - case '^': - case '&': - case '>': - case '<': - case '-': - case '+': - case '%': - case '/': - case '*': - case '!': - case '~': - case '(': - case ')': - type = token->type; - break; - - default: - break; - } - - return type; -} - -void yyerror(Context *context, const char *reason) -{ - context->diagnostics->report(pp::Diagnostics::PP_INVALID_EXPRESSION, - context->token->location, - reason); -} - -namespace pp { - -ExpressionParser::ExpressionParser(Lexer *lexer, Diagnostics *diagnostics) - : mLexer(lexer), - mDiagnostics(diagnostics) -{ -} - -bool ExpressionParser::parse(Token *token, - int *result, - bool parsePresetToken, - const ErrorSettings &errorSettings, - bool *valid) -{ - Context context; - context.diagnostics = mDiagnostics; - context.lexer = mLexer; - context.token = token; - context.result = result; - context.ignoreErrors = 0; - context.parsePresetToken = parsePresetToken; - context.errorSettings = errorSettings; - context.valid = valid; - int ret = yyparse(&context); - switch (ret) - { - case 0: - case 1: - break; - - case 2: - mDiagnostics->report(Diagnostics::PP_OUT_OF_MEMORY, token->location, ""); - break; - - default: - assert(false); - mDiagnostics->report(Diagnostics::PP_INTERNAL_ERROR, token->location, ""); - break; - } - - return ret == 0; -} - -} // namespace pp diff --git a/src/3rdparty/angle/src/compiler/preprocessor/Input.cpp b/src/3rdparty/angle/src/compiler/preprocessor/Input.cpp deleted file mode 100644 index 0f2327b823..0000000000 --- a/src/3rdparty/angle/src/compiler/preprocessor/Input.cpp +++ /dev/null @@ -1,129 +0,0 @@ -// -// Copyright (c) 2011 The ANGLE Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// - -#include "compiler/preprocessor/Input.h" - -#include <algorithm> -#include <cstring> - -#include "common/debug.h" - -namespace pp -{ - -Input::Input() : mCount(0), mString(0) -{ -} - -Input::~Input() -{ -} - -Input::Input(size_t count, const char *const string[], const int length[]) - : mCount(count), mString(string) -{ - mLength.reserve(mCount); - for (size_t i = 0; i < mCount; ++i) - { - int len = length ? length[i] : -1; - mLength.push_back(len < 0 ? std::strlen(mString[i]) : len); - } -} - -const char *Input::skipChar() -{ - // This function should only be called when there is a character to skip. - ASSERT(mReadLoc.cIndex < mLength[mReadLoc.sIndex]); - ++mReadLoc.cIndex; - if (mReadLoc.cIndex == mLength[mReadLoc.sIndex]) - { - ++mReadLoc.sIndex; - mReadLoc.cIndex = 0; - } - if (mReadLoc.sIndex >= mCount) - { - return nullptr; - } - return mString[mReadLoc.sIndex] + mReadLoc.cIndex; -} - -size_t Input::read(char *buf, size_t maxSize, int *lineNo) -{ - size_t nRead = 0; - // The previous call to read might have stopped copying the string when encountering a line - // continuation. Check for this possibility first. - if (mReadLoc.sIndex < mCount && maxSize > 0) - { - const char *c = mString[mReadLoc.sIndex] + mReadLoc.cIndex; - if ((*c) == '\\') - { - c = skipChar(); - if (c != nullptr && (*c) == '\n') - { - // Line continuation of backslash + newline. - skipChar(); - // Fake an EOF if the line number would overflow. - if (*lineNo == INT_MAX) - { - return 0; - } - ++(*lineNo); - } - else if (c != nullptr && (*c) == '\r') - { - // Line continuation. Could be backslash + '\r\n' or just backslash + '\r'. - c = skipChar(); - if (c != nullptr && (*c) == '\n') - { - skipChar(); - } - // Fake an EOF if the line number would overflow. - if (*lineNo == INT_MAX) - { - return 0; - } - ++(*lineNo); - } - else - { - // Not line continuation, so write the skipped backslash to buf. - *buf = '\\'; - ++nRead; - } - } - } - - size_t maxRead = maxSize; - while ((nRead < maxRead) && (mReadLoc.sIndex < mCount)) - { - size_t size = mLength[mReadLoc.sIndex] - mReadLoc.cIndex; - size = std::min(size, maxSize); - for (size_t i = 0; i < size; ++i) - { - // Stop if a possible line continuation is encountered. - // It will be processed on the next call on input, which skips it - // and increments line number if necessary. - if (*(mString[mReadLoc.sIndex] + mReadLoc.cIndex + i) == '\\') - { - size = i; - maxRead = nRead + size; // Stop reading right before the backslash. - } - } - std::memcpy(buf + nRead, mString[mReadLoc.sIndex] + mReadLoc.cIndex, size); - nRead += size; - mReadLoc.cIndex += size; - - // Advance string if we reached the end of current string. - if (mReadLoc.cIndex == mLength[mReadLoc.sIndex]) - { - ++mReadLoc.sIndex; - mReadLoc.cIndex = 0; - } - } - return nRead; -} - -} // namespace pp diff --git a/src/3rdparty/angle/src/compiler/preprocessor/Input.h b/src/3rdparty/angle/src/compiler/preprocessor/Input.h deleted file mode 100644 index 8c7c7ee19e..0000000000 --- a/src/3rdparty/angle/src/compiler/preprocessor/Input.h +++ /dev/null @@ -1,54 +0,0 @@ -// -// Copyright (c) 2011 The ANGLE Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// - -#ifndef COMPILER_PREPROCESSOR_INPUT_H_ -#define COMPILER_PREPROCESSOR_INPUT_H_ - -#include <cstddef> -#include <vector> - -namespace pp -{ - -// Holds and reads input for Lexer. -class Input -{ - public: - Input(); - ~Input(); - Input(size_t count, const char *const string[], const int length[]); - - size_t count() const { return mCount; } - const char *string(size_t index) const { return mString[index]; } - size_t length(size_t index) const { return mLength[index]; } - - size_t read(char *buf, size_t maxSize, int *lineNo); - - struct Location - { - size_t sIndex; // String index; - size_t cIndex; // Char index. - - Location() : sIndex(0), cIndex(0) {} - }; - const Location &readLoc() const { return mReadLoc; } - - private: - // Skip a character and return the next character after the one that was skipped. - // Return nullptr if data runs out. - const char *skipChar(); - - // Input. - size_t mCount; - const char *const *mString; - std::vector<size_t> mLength; - - Location mReadLoc; -}; - -} // namespace pp - -#endif // COMPILER_PREPROCESSOR_INPUT_H_ diff --git a/src/3rdparty/angle/src/compiler/preprocessor/Lexer.cpp b/src/3rdparty/angle/src/compiler/preprocessor/Lexer.cpp deleted file mode 100644 index 89cb3cf44e..0000000000 --- a/src/3rdparty/angle/src/compiler/preprocessor/Lexer.cpp +++ /dev/null @@ -1,16 +0,0 @@ -// -// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// - -#include "compiler/preprocessor/Lexer.h" - -namespace pp -{ - -Lexer::~Lexer() -{ -} - -} // namespace pp diff --git a/src/3rdparty/angle/src/compiler/preprocessor/Lexer.h b/src/3rdparty/angle/src/compiler/preprocessor/Lexer.h deleted file mode 100644 index 775bc0a202..0000000000 --- a/src/3rdparty/angle/src/compiler/preprocessor/Lexer.h +++ /dev/null @@ -1,27 +0,0 @@ -// -// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// - -#ifndef COMPILER_PREPROCESSOR_LEXER_H_ -#define COMPILER_PREPROCESSOR_LEXER_H_ - -#include "common/angleutils.h" - -namespace pp -{ - -struct Token; - -class Lexer : angle::NonCopyable -{ - public: - virtual ~Lexer(); - - virtual void lex(Token *token) = 0; -}; - -} // namespace pp - -#endif // COMPILER_PREPROCESSOR_LEXER_H_ diff --git a/src/3rdparty/angle/src/compiler/preprocessor/Macro.cpp b/src/3rdparty/angle/src/compiler/preprocessor/Macro.cpp deleted file mode 100644 index 52e2312fe6..0000000000 --- a/src/3rdparty/angle/src/compiler/preprocessor/Macro.cpp +++ /dev/null @@ -1,44 +0,0 @@ -// -// Copyright (c) 2011 The ANGLE Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// - -#include "compiler/preprocessor/Macro.h" - -#include "common/angleutils.h" -#include "compiler/preprocessor/Token.h" - -namespace pp -{ - -Macro::Macro() : predefined(false), disabled(false), expansionCount(0), type(kTypeObj) -{ -} - -Macro::~Macro() -{ -} - -bool Macro::equals(const Macro &other) const -{ - return (type == other.type) && (name == other.name) && (parameters == other.parameters) && - (replacements == other.replacements); -} - -void PredefineMacro(MacroSet *macroSet, const char *name, int value) -{ - Token token; - token.type = Token::CONST_INT; - token.text = ToString(value); - - std::shared_ptr<Macro> macro = std::make_shared<Macro>(); - macro->predefined = true; - macro->type = Macro::kTypeObj; - macro->name = name; - macro->replacements.push_back(token); - - (*macroSet)[name] = macro; -} - -} // namespace pp diff --git a/src/3rdparty/angle/src/compiler/preprocessor/Macro.h b/src/3rdparty/angle/src/compiler/preprocessor/Macro.h deleted file mode 100644 index c42e172ef9..0000000000 --- a/src/3rdparty/angle/src/compiler/preprocessor/Macro.h +++ /dev/null @@ -1,50 +0,0 @@ -// -// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// - -#ifndef COMPILER_PREPROCESSOR_MACRO_H_ -#define COMPILER_PREPROCESSOR_MACRO_H_ - -#include <map> -#include <memory> -#include <string> -#include <vector> - -namespace pp -{ - -struct Token; - -struct Macro -{ - enum Type - { - kTypeObj, - kTypeFunc - }; - typedef std::vector<std::string> Parameters; - typedef std::vector<Token> Replacements; - - Macro(); - ~Macro(); - bool equals(const Macro &other) const; - - bool predefined; - mutable bool disabled; - mutable int expansionCount; - - Type type; - std::string name; - Parameters parameters; - Replacements replacements; -}; - -typedef std::map<std::string, std::shared_ptr<Macro>> MacroSet; - -void PredefineMacro(MacroSet *macroSet, const char *name, int value); - -} // namespace pp - -#endif // COMPILER_PREPROCESSOR_MACRO_H_ diff --git a/src/3rdparty/angle/src/compiler/preprocessor/MacroExpander.cpp b/src/3rdparty/angle/src/compiler/preprocessor/MacroExpander.cpp deleted file mode 100644 index d88d3a6853..0000000000 --- a/src/3rdparty/angle/src/compiler/preprocessor/MacroExpander.cpp +++ /dev/null @@ -1,481 +0,0 @@ -// -// Copyright (c) 2011 The ANGLE Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// - -#include "compiler/preprocessor/MacroExpander.h" - -#include <algorithm> - -#include "common/debug.h" -#include "compiler/preprocessor/DiagnosticsBase.h" -#include "compiler/preprocessor/Token.h" - -namespace pp -{ - -namespace -{ - -const size_t kMaxContextTokens = 10000; - -class TokenLexer : public Lexer -{ - public: - typedef std::vector<Token> TokenVector; - - TokenLexer(TokenVector *tokens) - { - tokens->swap(mTokens); - mIter = mTokens.begin(); - } - - void lex(Token *token) override - { - if (mIter == mTokens.end()) - { - token->reset(); - token->type = Token::LAST; - } - else - { - *token = *mIter++; - } - } - - private: - TokenVector mTokens; - TokenVector::const_iterator mIter; -}; - -} // anonymous namespace - -class MacroExpander::ScopedMacroReenabler final : angle::NonCopyable -{ - public: - ScopedMacroReenabler(MacroExpander *expander); - ~ScopedMacroReenabler(); - - private: - MacroExpander *mExpander; -}; - -MacroExpander::ScopedMacroReenabler::ScopedMacroReenabler(MacroExpander *expander) - : mExpander(expander) -{ - mExpander->mDeferReenablingMacros = true; -} - -MacroExpander::ScopedMacroReenabler::~ScopedMacroReenabler() -{ - mExpander->mDeferReenablingMacros = false; - for (auto macro : mExpander->mMacrosToReenable) - { - // Copying the string here by using substr is a check for use-after-free. It detects - // use-after-free more reliably than just toggling the disabled flag. - ASSERT(macro->name.substr() != ""); - macro->disabled = false; - } - mExpander->mMacrosToReenable.clear(); -} - -MacroExpander::MacroExpander(Lexer *lexer, - MacroSet *macroSet, - Diagnostics *diagnostics, - int allowedMacroExpansionDepth) - : mLexer(lexer), - mMacroSet(macroSet), - mDiagnostics(diagnostics), - mTotalTokensInContexts(0), - mAllowedMacroExpansionDepth(allowedMacroExpansionDepth), - mDeferReenablingMacros(false) -{ -} - -MacroExpander::~MacroExpander() -{ - ASSERT(mMacrosToReenable.empty()); - for (MacroContext *context : mContextStack) - { - delete context; - } -} - -void MacroExpander::lex(Token *token) -{ - while (true) - { - getToken(token); - - if (token->type != Token::IDENTIFIER) - break; - - if (token->expansionDisabled()) - break; - - MacroSet::const_iterator iter = mMacroSet->find(token->text); - if (iter == mMacroSet->end()) - break; - - std::shared_ptr<Macro> macro = iter->second; - if (macro->disabled) - { - // If a particular token is not expanded, it is never expanded. - token->setExpansionDisabled(true); - break; - } - - // Bump the expansion count before peeking if the next token is a '(' - // otherwise there could be a #undef of the macro before the next token. - macro->expansionCount++; - if ((macro->type == Macro::kTypeFunc) && !isNextTokenLeftParen()) - { - // If the token immediately after the macro name is not a '(', - // this macro should not be expanded. - macro->expansionCount--; - break; - } - - pushMacro(macro, *token); - } -} - -void MacroExpander::getToken(Token *token) -{ - if (mReserveToken.get()) - { - *token = *mReserveToken; - mReserveToken.reset(); - return; - } - - // First pop all empty macro contexts. - while (!mContextStack.empty() && mContextStack.back()->empty()) - { - popMacro(); - } - - if (!mContextStack.empty()) - { - *token = mContextStack.back()->get(); - } - else - { - ASSERT(mTotalTokensInContexts == 0); - mLexer->lex(token); - } -} - -void MacroExpander::ungetToken(const Token &token) -{ - if (!mContextStack.empty()) - { - MacroContext *context = mContextStack.back(); - context->unget(); - ASSERT(context->replacements[context->index] == token); - } - else - { - ASSERT(!mReserveToken.get()); - mReserveToken.reset(new Token(token)); - } -} - -bool MacroExpander::isNextTokenLeftParen() -{ - Token token; - getToken(&token); - - bool lparen = token.type == '('; - ungetToken(token); - - return lparen; -} - -bool MacroExpander::pushMacro(std::shared_ptr<Macro> macro, const Token &identifier) -{ - ASSERT(!macro->disabled); - ASSERT(!identifier.expansionDisabled()); - ASSERT(identifier.type == Token::IDENTIFIER); - ASSERT(identifier.text == macro->name); - - std::vector<Token> replacements; - if (!expandMacro(*macro, identifier, &replacements)) - return false; - - // Macro is disabled for expansion until it is popped off the stack. - macro->disabled = true; - - MacroContext *context = new MacroContext; - context->macro = macro; - context->replacements.swap(replacements); - mContextStack.push_back(context); - mTotalTokensInContexts += context->replacements.size(); - return true; -} - -void MacroExpander::popMacro() -{ - ASSERT(!mContextStack.empty()); - - MacroContext *context = mContextStack.back(); - mContextStack.pop_back(); - - ASSERT(context->empty()); - ASSERT(context->macro->disabled); - ASSERT(context->macro->expansionCount > 0); - if (mDeferReenablingMacros) - { - mMacrosToReenable.push_back(context->macro); - } - else - { - context->macro->disabled = false; - } - context->macro->expansionCount--; - mTotalTokensInContexts -= context->replacements.size(); - delete context; -} - -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::collectMacroArgs(const Macro ¯o, - const Token &identifier, - std::vector<MacroArg> *args, - SourceLocation *closingParenthesisLocation) -{ - Token token; - getToken(&token); - ASSERT(token.type == '('); - - args->push_back(MacroArg()); - - // Defer reenabling macros until args collection is finished to avoid the possibility of - // infinite recursion. Otherwise infinite recursion might happen when expanding the args after - // macros have been popped from the context stack when parsing the args. - ScopedMacroReenabler deferReenablingMacros(this); - - int openParens = 1; - while (openParens != 0) - { - getToken(&token); - - if (token.type == Token::LAST) - { - mDiagnostics->report(Diagnostics::PP_MACRO_UNTERMINATED_INVOCATION, identifier.location, - identifier.text); - // Do not lose EOF token. - ungetToken(token); - return false; - } - - bool isArg = false; // True if token is part of the current argument. - switch (token.type) - { - case '(': - ++openParens; - isArg = true; - break; - case ')': - --openParens; - isArg = openParens != 0; - *closingParenthesisLocation = token.location; - break; - case ',': - // The individual arguments are separated by comma tokens, but - // the comma tokens between matching inner parentheses do not - // seperate arguments. - if (openParens == 1) - args->push_back(MacroArg()); - isArg = openParens != 1; - break; - default: - isArg = true; - break; - } - if (isArg) - { - MacroArg &arg = args->back(); - // Initial whitespace is not part of the argument. - if (arg.empty()) - token.setHasLeadingSpace(false); - arg.push_back(token); - } - } - - const Macro::Parameters ¶ms = macro.parameters; - // If there is only one empty argument, it is equivalent to no argument. - if (params.empty() && (args->size() == 1) && args->front().empty()) - { - args->clear(); - } - // Validate the number of arguments. - if (args->size() != params.size()) - { - Diagnostics::ID id = args->size() < macro.parameters.size() - ? Diagnostics::PP_MACRO_TOO_FEW_ARGS - : Diagnostics::PP_MACRO_TOO_MANY_ARGS; - mDiagnostics->report(id, identifier.location, identifier.text); - return false; - } - - // Pre-expand each argument before substitution. - // This step expands each argument individually before they are - // inserted into the macro body. - size_t numTokens = 0; - for (auto &arg : *args) - { - TokenLexer lexer(&arg); - if (mAllowedMacroExpansionDepth < 1) - { - mDiagnostics->report(Diagnostics::PP_MACRO_INVOCATION_CHAIN_TOO_DEEP, token.location, - token.text); - return false; - } - MacroExpander expander(&lexer, mMacroSet, mDiagnostics, mAllowedMacroExpansionDepth - 1); - - arg.clear(); - expander.lex(&token); - while (token.type != Token::LAST) - { - arg.push_back(token); - expander.lex(&token); - numTokens++; - if (numTokens + mTotalTokensInContexts > kMaxContextTokens) - { - mDiagnostics->report(Diagnostics::PP_OUT_OF_MEMORY, token.location, token.text); - return false; - } - } - } - return true; -} - -void MacroExpander::replaceMacroParams(const Macro ¯o, - const std::vector<MacroArg> &args, - std::vector<Token> *replacements) -{ - for (std::size_t i = 0; i < macro.replacements.size(); ++i) - { - if (!replacements->empty() && - replacements->size() + mTotalTokensInContexts > kMaxContextTokens) - { - const Token &token = replacements->back(); - mDiagnostics->report(Diagnostics::PP_OUT_OF_MEMORY, token.location, token.text); - return; - } - - const Token &repl = macro.replacements[i]; - if (repl.type != Token::IDENTIFIER) - { - replacements->push_back(repl); - continue; - } - - // TODO(alokp): Optimize this. - // There is no need to search for macro params every time. - // The param index can be cached with the replacement token. - Macro::Parameters::const_iterator iter = - std::find(macro.parameters.begin(), macro.parameters.end(), repl.text); - if (iter == macro.parameters.end()) - { - replacements->push_back(repl); - continue; - } - - std::size_t iArg = std::distance(macro.parameters.begin(), iter); - const MacroArg &arg = args[iArg]; - if (arg.empty()) - { - continue; - } - std::size_t iRepl = replacements->size(); - replacements->insert(replacements->end(), arg.begin(), arg.end()); - // The replacement token inherits padding properties from - // macro replacement token. - replacements->at(iRepl).setHasLeadingSpace(repl.hasLeadingSpace()); - } -} - -MacroExpander::MacroContext::MacroContext() : macro(0), index(0) -{ -} - -MacroExpander::MacroContext::~MacroContext() -{ -} - -bool MacroExpander::MacroContext::empty() const -{ - return index == replacements.size(); -} - -const Token &MacroExpander::MacroContext::get() -{ - return replacements[index++]; -} - -void MacroExpander::MacroContext::unget() -{ - ASSERT(index > 0); - --index; -} - -} // namespace pp diff --git a/src/3rdparty/angle/src/compiler/preprocessor/MacroExpander.h b/src/3rdparty/angle/src/compiler/preprocessor/MacroExpander.h deleted file mode 100644 index fae7676fb0..0000000000 --- a/src/3rdparty/angle/src/compiler/preprocessor/MacroExpander.h +++ /dev/null @@ -1,83 +0,0 @@ -// -// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// - -#ifndef COMPILER_PREPROCESSOR_MACROEXPANDER_H_ -#define COMPILER_PREPROCESSOR_MACROEXPANDER_H_ - -#include <memory> -#include <vector> - -#include "compiler/preprocessor/Lexer.h" -#include "compiler/preprocessor/Macro.h" - -namespace pp -{ - -class Diagnostics; -struct SourceLocation; - -class MacroExpander : public Lexer -{ - public: - MacroExpander(Lexer *lexer, - MacroSet *macroSet, - Diagnostics *diagnostics, - int allowedMacroExpansionDepth); - ~MacroExpander() override; - - void lex(Token *token) override; - - private: - void getToken(Token *token); - void ungetToken(const Token &token); - bool isNextTokenLeftParen(); - - bool pushMacro(std::shared_ptr<Macro> macro, const Token &identifier); - void popMacro(); - - bool expandMacro(const Macro ¯o, const Token &identifier, std::vector<Token> *replacements); - - typedef std::vector<Token> MacroArg; - bool collectMacroArgs(const Macro ¯o, - const Token &identifier, - std::vector<MacroArg> *args, - SourceLocation *closingParenthesisLocation); - void replaceMacroParams(const Macro ¯o, - const std::vector<MacroArg> &args, - std::vector<Token> *replacements); - - struct MacroContext - { - MacroContext(); - ~MacroContext(); - bool empty() const; - const Token &get(); - void unget(); - - std::shared_ptr<Macro> macro; - std::size_t index; - std::vector<Token> replacements; - }; - - Lexer *mLexer; - MacroSet *mMacroSet; - Diagnostics *mDiagnostics; - - std::unique_ptr<Token> mReserveToken; - std::vector<MacroContext *> mContextStack; - size_t mTotalTokensInContexts; - - int mAllowedMacroExpansionDepth; - - bool mDeferReenablingMacros; - std::vector<std::shared_ptr<Macro>> mMacrosToReenable; - - class ScopedMacroReenabler; -}; - -} // namespace pp - -#endif // COMPILER_PREPROCESSOR_MACROEXPANDER_H_ diff --git a/src/3rdparty/angle/src/compiler/preprocessor/Preprocessor.cpp b/src/3rdparty/angle/src/compiler/preprocessor/Preprocessor.cpp deleted file mode 100644 index 349c7b06c7..0000000000 --- a/src/3rdparty/angle/src/compiler/preprocessor/Preprocessor.cpp +++ /dev/null @@ -1,107 +0,0 @@ -// -// Copyright (c) 2011 The ANGLE Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// - -#include "compiler/preprocessor/Preprocessor.h" - -#include "common/debug.h" -#include "compiler/preprocessor/DiagnosticsBase.h" -#include "compiler/preprocessor/DirectiveParser.h" -#include "compiler/preprocessor/Macro.h" -#include "compiler/preprocessor/MacroExpander.h" -#include "compiler/preprocessor/Token.h" -#include "compiler/preprocessor/Tokenizer.h" - -namespace pp -{ - -struct PreprocessorImpl -{ - Diagnostics *diagnostics; - MacroSet macroSet; - Tokenizer tokenizer; - DirectiveParser directiveParser; - MacroExpander macroExpander; - - PreprocessorImpl(Diagnostics *diag, - DirectiveHandler *directiveHandler, - const PreprocessorSettings &settings) - : diagnostics(diag), - tokenizer(diag), - directiveParser(&tokenizer, - ¯oSet, - diag, - directiveHandler, - settings.maxMacroExpansionDepth), - macroExpander(&directiveParser, ¯oSet, diag, settings.maxMacroExpansionDepth) - { - } -}; - -Preprocessor::Preprocessor(Diagnostics *diagnostics, - DirectiveHandler *directiveHandler, - const PreprocessorSettings &settings) -{ - mImpl = new PreprocessorImpl(diagnostics, directiveHandler, settings); -} - -Preprocessor::~Preprocessor() -{ - delete mImpl; -} - -bool Preprocessor::init(size_t count, const char *const string[], const int length[]) -{ - static const int kDefaultGLSLVersion = 100; - - // Add standard pre-defined macros. - predefineMacro("__LINE__", 0); - predefineMacro("__FILE__", 0); - predefineMacro("__VERSION__", kDefaultGLSLVersion); - predefineMacro("GL_ES", 1); - - return mImpl->tokenizer.init(count, string, length); -} - -void Preprocessor::predefineMacro(const char *name, int value) -{ - PredefineMacro(&mImpl->macroSet, name, value); -} - -void Preprocessor::lex(Token *token) -{ - bool validToken = false; - while (!validToken) - { - mImpl->macroExpander.lex(token); - switch (token->type) - { - // We should not be returning internal preprocessing tokens. - // Convert preprocessing tokens to compiler tokens or report - // diagnostics. - case Token::PP_HASH: - UNREACHABLE(); - break; - case Token::PP_NUMBER: - mImpl->diagnostics->report(Diagnostics::PP_INVALID_NUMBER, token->location, - token->text); - break; - case Token::PP_OTHER: - mImpl->diagnostics->report(Diagnostics::PP_INVALID_CHARACTER, token->location, - token->text); - break; - default: - validToken = true; - break; - } - } -} - -void Preprocessor::setMaxTokenSize(size_t maxTokenSize) -{ - mImpl->tokenizer.setMaxTokenSize(maxTokenSize); -} - -} // namespace pp diff --git a/src/3rdparty/angle/src/compiler/preprocessor/Preprocessor.h b/src/3rdparty/angle/src/compiler/preprocessor/Preprocessor.h deleted file mode 100644 index 2fe504f7f9..0000000000 --- a/src/3rdparty/angle/src/compiler/preprocessor/Preprocessor.h +++ /dev/null @@ -1,60 +0,0 @@ -// -// Copyright (c) 2011 The ANGLE Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// - -#ifndef COMPILER_PREPROCESSOR_PREPROCESSOR_H_ -#define COMPILER_PREPROCESSOR_PREPROCESSOR_H_ - -#include <cstddef> - -#include "common/angleutils.h" - -namespace pp -{ - -class Diagnostics; -class DirectiveHandler; -struct PreprocessorImpl; -struct Token; - -struct PreprocessorSettings : private angle::NonCopyable -{ - PreprocessorSettings() : maxMacroExpansionDepth(1000) {} - int maxMacroExpansionDepth; -}; - -class Preprocessor : angle::NonCopyable -{ - public: - Preprocessor(Diagnostics *diagnostics, - DirectiveHandler *directiveHandler, - const PreprocessorSettings &settings); - ~Preprocessor(); - - // count: specifies the number of elements in the string and length arrays. - // string: specifies an array of pointers to strings. - // length: specifies an array of string lengths. - // If length is NULL, each string is assumed to be null terminated. - // If length is a value other than NULL, it points to an array containing - // a string length for each of the corresponding elements of string. - // Each element in the length array may contain the length of the - // corresponding string or a value less than 0 to indicate that the string - // is null terminated. - bool init(size_t count, const char *const string[], const int length[]); - // Adds a pre-defined macro. - void predefineMacro(const char *name, int value); - - void lex(Token *token); - - // Set maximum preprocessor token size - void setMaxTokenSize(size_t maxTokenSize); - - private: - PreprocessorImpl *mImpl; -}; - -} // namespace pp - -#endif // COMPILER_PREPROCESSOR_PREPROCESSOR_H_ diff --git a/src/3rdparty/angle/src/compiler/preprocessor/SourceLocation.h b/src/3rdparty/angle/src/compiler/preprocessor/SourceLocation.h deleted file mode 100644 index 51908a3b4b..0000000000 --- a/src/3rdparty/angle/src/compiler/preprocessor/SourceLocation.h +++ /dev/null @@ -1,39 +0,0 @@ -// -// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// - -#ifndef COMPILER_PREPROCESSOR_SOURCELOCATION_H_ -#define COMPILER_PREPROCESSOR_SOURCELOCATION_H_ - -namespace pp -{ - -struct SourceLocation -{ - SourceLocation() : file(0), line(0) {} - SourceLocation(int f, int l) : file(f), line(l) {} - - bool equals(const SourceLocation &other) const - { - return (file == other.file) && (line == other.line); - } - - int file; - int line; -}; - -inline bool operator==(const SourceLocation &lhs, const SourceLocation &rhs) -{ - return lhs.equals(rhs); -} - -inline bool operator!=(const SourceLocation &lhs, const SourceLocation &rhs) -{ - return !lhs.equals(rhs); -} - -} // namespace pp - -#endif // COMPILER_PREPROCESSOR_SOURCELOCATION_H_ diff --git a/src/3rdparty/angle/src/compiler/preprocessor/Token.cpp b/src/3rdparty/angle/src/compiler/preprocessor/Token.cpp deleted file mode 100644 index ce0ce94f49..0000000000 --- a/src/3rdparty/angle/src/compiler/preprocessor/Token.cpp +++ /dev/null @@ -1,80 +0,0 @@ -// -// Copyright (c) 2011 The ANGLE Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// - -#include "compiler/preprocessor/Token.h" - -#include "common/debug.h" -#include "compiler/preprocessor/numeric_lex.h" - -namespace pp -{ - -void Token::reset() -{ - type = 0; - flags = 0; - location = SourceLocation(); - text.clear(); -} - -bool Token::equals(const Token &other) const -{ - return (type == other.type) && (flags == other.flags) && (location == other.location) && - (text == other.text); -} - -void Token::setAtStartOfLine(bool start) -{ - if (start) - flags |= AT_START_OF_LINE; - else - flags &= ~AT_START_OF_LINE; -} - -void Token::setHasLeadingSpace(bool space) -{ - if (space) - flags |= HAS_LEADING_SPACE; - else - flags &= ~HAS_LEADING_SPACE; -} - -void Token::setExpansionDisabled(bool disable) -{ - if (disable) - flags |= EXPANSION_DISABLED; - else - flags &= ~EXPANSION_DISABLED; -} - -bool Token::iValue(int *value) const -{ - ASSERT(type == CONST_INT); - return numeric_lex_int(text, value); -} - -bool Token::uValue(unsigned int *value) const -{ - ASSERT(type == CONST_INT); - return numeric_lex_int(text, value); -} - -bool Token::fValue(float *value) const -{ - ASSERT(type == CONST_FLOAT); - return numeric_lex_float(text, value); -} - -std::ostream &operator<<(std::ostream &out, const Token &token) -{ - if (token.hasLeadingSpace()) - out << " "; - - out << token.text; - return out; -} - -} // namespace pp diff --git a/src/3rdparty/angle/src/compiler/preprocessor/Token.h b/src/3rdparty/angle/src/compiler/preprocessor/Token.h deleted file mode 100644 index 26732ab64d..0000000000 --- a/src/3rdparty/angle/src/compiler/preprocessor/Token.h +++ /dev/null @@ -1,109 +0,0 @@ -// -// Copyright (c) 2011 The ANGLE Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// - -#ifndef COMPILER_PREPROCESSOR_TOKEN_H_ -#define COMPILER_PREPROCESSOR_TOKEN_H_ - -#include <ostream> -#include <string> - -#include "compiler/preprocessor/SourceLocation.h" - -namespace pp -{ - -struct Token -{ - enum Type - { - // Calling this ERROR causes a conflict with wingdi.h - GOT_ERROR = -1, - LAST = 0, // EOF. - - IDENTIFIER = 258, - - CONST_INT, - CONST_FLOAT, - - OP_INC, - OP_DEC, - OP_LEFT, - OP_RIGHT, - OP_LE, - OP_GE, - OP_EQ, - OP_NE, - OP_AND, - OP_XOR, - OP_OR, - OP_ADD_ASSIGN, - OP_SUB_ASSIGN, - OP_MUL_ASSIGN, - OP_DIV_ASSIGN, - OP_MOD_ASSIGN, - OP_LEFT_ASSIGN, - OP_RIGHT_ASSIGN, - OP_AND_ASSIGN, - OP_XOR_ASSIGN, - OP_OR_ASSIGN, - - // Preprocessing token types. - // These types are used by the preprocessor internally. - // Preprocessor clients must not depend or check for them. - PP_HASH, - PP_NUMBER, - PP_OTHER - }; - enum Flags - { - AT_START_OF_LINE = 1 << 0, - HAS_LEADING_SPACE = 1 << 1, - EXPANSION_DISABLED = 1 << 2 - }; - - Token() : type(0), flags(0) {} - - void reset(); - bool equals(const Token &other) const; - - // Returns true if this is the first token on line. - // It disregards any leading whitespace. - bool atStartOfLine() const { return (flags & AT_START_OF_LINE) != 0; } - void setAtStartOfLine(bool start); - - bool hasLeadingSpace() const { return (flags & HAS_LEADING_SPACE) != 0; } - void setHasLeadingSpace(bool space); - - bool expansionDisabled() const { return (flags & EXPANSION_DISABLED) != 0; } - void setExpansionDisabled(bool disable); - - // Converts text into numeric value for CONST_INT and CONST_FLOAT token. - // Returns false if the parsed value cannot fit into an int or float. - bool iValue(int *value) const; - bool uValue(unsigned int *value) const; - bool fValue(float *value) const; - - int type; - unsigned int flags; - SourceLocation location; - std::string text; -}; - -inline bool operator==(const Token &lhs, const Token &rhs) -{ - return lhs.equals(rhs); -} - -inline bool operator!=(const Token &lhs, const Token &rhs) -{ - return !lhs.equals(rhs); -} - -std::ostream &operator<<(std::ostream &out, const Token &token); - -} // namepsace pp - -#endif // COMPILER_PREPROCESSOR_TOKEN_H_ diff --git a/src/3rdparty/angle/src/compiler/preprocessor/Tokenizer.h b/src/3rdparty/angle/src/compiler/preprocessor/Tokenizer.h deleted file mode 100644 index af4fd7ce7b..0000000000 --- a/src/3rdparty/angle/src/compiler/preprocessor/Tokenizer.h +++ /dev/null @@ -1,58 +0,0 @@ -// -// Copyright (c) 2012-2014 The ANGLE Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// - -#ifndef COMPILER_PREPROCESSOR_TOKENIZER_H_ -#define COMPILER_PREPROCESSOR_TOKENIZER_H_ - -#include "common/angleutils.h" -#include "compiler/preprocessor/Input.h" -#include "compiler/preprocessor/Lexer.h" - -namespace pp -{ - -class Diagnostics; - -class Tokenizer : public Lexer -{ - public: - struct Context - { - Diagnostics *diagnostics; - - Input input; - // The location where yytext points to. Token location should track - // scanLoc instead of Input::mReadLoc because they may not be the same - // if text is buffered up in the scanner input buffer. - Input::Location scanLoc; - - bool leadingSpace; - bool lineStart; - }; - - Tokenizer(Diagnostics *diagnostics); - ~Tokenizer() override; - - bool init(size_t count, const char *const string[], const int length[]); - - void setFileNumber(int file); - void setLineNumber(int line); - void setMaxTokenSize(size_t maxTokenSize); - - void lex(Token *token) override; - - private: - bool initScanner(); - void destroyScanner(); - - void *mHandle; // Scanner handle. - Context mContext; // Scanner extra. - size_t mMaxTokenSize; // Maximum token size -}; - -} // namespace pp - -#endif // COMPILER_PREPROCESSOR_TOKENIZER_H_ diff --git a/src/3rdparty/angle/src/compiler/preprocessor/Tokenizer.l b/src/3rdparty/angle/src/compiler/preprocessor/Tokenizer.l deleted file mode 100644 index 096812d45f..0000000000 --- a/src/3rdparty/angle/src/compiler/preprocessor/Tokenizer.l +++ /dev/null @@ -1,384 +0,0 @@ -/* -// -// Copyright (c) 2002-2014 The ANGLE Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// - -This file contains the Lex specification for GLSL ES preprocessor. -Based on Microsoft Visual Studio 2010 Preprocessor Grammar: -http://msdn.microsoft.com/en-us/library/2scxys89.aspx - -IF YOU MODIFY THIS FILE YOU ALSO NEED TO RUN generate_parser.sh. -*/ - -%top{ -// -// Copyright (c) 2011-2014 The ANGLE Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// - -// This file is auto-generated by generate_parser.sh. DO NOT EDIT! -} - -%{ -#if defined(_MSC_VER) -#pragma warning(disable: 4005) -#endif - -#include "compiler/preprocessor/Tokenizer.h" - -#include "compiler/preprocessor/DiagnosticsBase.h" -#include "compiler/preprocessor/Token.h" - -#if defined(__GNUC__) -// Triggered by the auto-generated yy_fatal_error function. -#pragma GCC diagnostic ignored "-Wmissing-noreturn" -#elif defined(_MSC_VER) -#pragma warning(disable: 4244) -#endif - -// Workaround for flex using the register keyword, deprecated in C++11. -#ifdef __cplusplus -#if __cplusplus > 199711L -#define register -#endif -#endif - -typedef std::string YYSTYPE; -typedef pp::SourceLocation YYLTYPE; - -// Use the unused yycolumn variable to track file (string) number. -#define yyfileno yycolumn - -#define YY_USER_INIT \ - do { \ - yyfileno = 0; \ - yylineno = 1; \ - yyextra->leadingSpace = false; \ - yyextra->lineStart = true; \ - } while(0); - -#define YY_USER_ACTION \ - do \ - { \ - pp::Input* input = &yyextra->input; \ - pp::Input::Location* scanLoc = &yyextra->scanLoc; \ - while ((scanLoc->sIndex < input->count()) && \ - (scanLoc->cIndex >= input->length(scanLoc->sIndex))) \ - { \ - scanLoc->cIndex -= input->length(scanLoc->sIndex++); \ - ++yyfileno; yylineno = 1; \ - } \ - yylloc->file = yyfileno; \ - yylloc->line = yylineno; \ - scanLoc->cIndex += yyleng; \ - } while(0); - -#define YY_INPUT(buf, result, maxSize) \ - result = yyextra->input.read(buf, maxSize, &yylineno); - -%} - -%option noyywrap nounput never-interactive -%option reentrant bison-bridge bison-locations -%option prefix="pp" -%option extra-type="pp::Tokenizer::Context*" -%x COMMENT - -NEWLINE \n|\r|\r\n -IDENTIFIER [_a-zA-Z][_a-zA-Z0-9]* -PUNCTUATOR [][<>(){}.+-/*%^|&~=!:;,?] - -DECIMAL_CONSTANT [1-9][0-9]*[uU]? -OCTAL_CONSTANT 0[0-7]*[uU]? -HEXADECIMAL_CONSTANT 0[xX][0-9a-fA-F]+[uU]? - -DIGIT [0-9] -EXPONENT_PART [eE][+-]?{DIGIT}+ -FRACTIONAL_CONSTANT ({DIGIT}*"."{DIGIT}+)|({DIGIT}+".") - -%% - - /* Line comment */ -"//"[^\r\n]* - - /* Block comment */ - /* Line breaks are just counted - not returned. */ - /* The comment is replaced by a single space. */ -"/*" { BEGIN(COMMENT); } -<COMMENT>[^*\r\n]+ -<COMMENT>"*" -<COMMENT>{NEWLINE} { - if (yylineno == INT_MAX) - { - *yylval = "Integer overflow on line number"; - return pp::Token::GOT_ERROR; - } - ++yylineno; -} -<COMMENT>"*/" { - yyextra->leadingSpace = true; - BEGIN(INITIAL); -} - -# { - // # is only valid at start of line for preprocessor directives. - yylval->assign(1, yytext[0]); - return yyextra->lineStart ? pp::Token::PP_HASH : pp::Token::PP_OTHER; -} - -{IDENTIFIER} { - yylval->assign(yytext, yyleng); - return pp::Token::IDENTIFIER; -} - -({DECIMAL_CONSTANT}[uU]?)|({OCTAL_CONSTANT}[uU]?)|({HEXADECIMAL_CONSTANT}[uU]?) { - yylval->assign(yytext, yyleng); - return pp::Token::CONST_INT; -} - -({DIGIT}+{EXPONENT_PART}[fF]?)|({FRACTIONAL_CONSTANT}{EXPONENT_PART}?[fF]?) { - yylval->assign(yytext, yyleng); - return pp::Token::CONST_FLOAT; -} - - /* Anything that starts with a {DIGIT} or .{DIGIT} must be a number. */ - /* Rule to catch all invalid integers and floats. */ -({DIGIT}+[_a-zA-Z0-9.]*)|("."{DIGIT}+[_a-zA-Z0-9.]*) { - yylval->assign(yytext, yyleng); - return pp::Token::PP_NUMBER; -} - -"++" { - yylval->assign(yytext, yyleng); - return pp::Token::OP_INC; -} -"--" { - yylval->assign(yytext, yyleng); - return pp::Token::OP_DEC; -} -"<<" { - yylval->assign(yytext, yyleng); - return pp::Token::OP_LEFT; -} -">>" { - yylval->assign(yytext, yyleng); - return pp::Token::OP_RIGHT; -} -"<=" { - yylval->assign(yytext, yyleng); - return pp::Token::OP_LE; -} -">=" { - yylval->assign(yytext, yyleng); - return pp::Token::OP_GE; -} -"==" { - yylval->assign(yytext, yyleng); - return pp::Token::OP_EQ; -} -"!=" { - yylval->assign(yytext, yyleng); - return pp::Token::OP_NE; -} -"&&" { - yylval->assign(yytext, yyleng); - return pp::Token::OP_AND; -} -"^^" { - yylval->assign(yytext, yyleng); - return pp::Token::OP_XOR; -} -"||" { - yylval->assign(yytext, yyleng); - return pp::Token::OP_OR; -} -"+=" { - yylval->assign(yytext, yyleng); - return pp::Token::OP_ADD_ASSIGN; -} -"-=" { - yylval->assign(yytext, yyleng); - return pp::Token::OP_SUB_ASSIGN; -} -"*=" { - yylval->assign(yytext, yyleng); - return pp::Token::OP_MUL_ASSIGN; -} -"/=" { - yylval->assign(yytext, yyleng); - return pp::Token::OP_DIV_ASSIGN; -} -"%=" { - yylval->assign(yytext, yyleng); - return pp::Token::OP_MOD_ASSIGN; -} -"<<=" { - yylval->assign(yytext, yyleng); - return pp::Token::OP_LEFT_ASSIGN; -} -">>=" { - yylval->assign(yytext, yyleng); - return pp::Token::OP_RIGHT_ASSIGN; -} -"&=" { - yylval->assign(yytext, yyleng); - return pp::Token::OP_AND_ASSIGN; -} -"^=" { - yylval->assign(yytext, yyleng); - return pp::Token::OP_XOR_ASSIGN; -} -"|=" { - yylval->assign(yytext, yyleng); - return pp::Token::OP_OR_ASSIGN; -} - -{PUNCTUATOR} { - yylval->assign(1, yytext[0]); - return yytext[0]; -} - -[ \t\v\f]+ { yyextra->leadingSpace = true; } - -{NEWLINE} { - if (yylineno == INT_MAX) - { - *yylval = "Integer overflow on line number"; - return pp::Token::GOT_ERROR; - } - ++yylineno; - yylval->assign(1, '\n'); - return '\n'; -} - -. { - yylval->assign(1, yytext[0]); - return pp::Token::PP_OTHER; -} - -<*><<EOF>> { - // YY_USER_ACTION is not invoked for handling EOF. - // Set the location for EOF token manually. - pp::Input* input = &yyextra->input; - pp::Input::Location* scanLoc = &yyextra->scanLoc; - yy_size_t sIndexMax = input->count() ? input->count() - 1 : 0; - if (scanLoc->sIndex != sIndexMax) - { - // We can only reach here if there are empty strings at the - // end of the input. - scanLoc->sIndex = sIndexMax; scanLoc->cIndex = 0; - // FIXME: this is not 64-bit clean. - yyfileno = static_cast<int>(sIndexMax); yylineno = 1; - } - yylloc->file = yyfileno; - yylloc->line = yylineno; - yylval->clear(); - - // Line number overflows fake EOFs to exit early, check for this case. - if (yylineno == INT_MAX) { - yyextra->diagnostics->report(pp::Diagnostics::PP_TOKENIZER_ERROR, - pp::SourceLocation(yyfileno, yylineno), - "Integer overflow on line number"); - } - else if (YY_START == COMMENT) - { - yyextra->diagnostics->report(pp::Diagnostics::PP_EOF_IN_COMMENT, - pp::SourceLocation(yyfileno, yylineno), - "EOF while in a comment"); - } - yyterminate(); -} - -%% - -namespace pp { - -Tokenizer::Tokenizer(Diagnostics *diagnostics) : mHandle(nullptr), mMaxTokenSize(256) -{ - mContext.diagnostics = diagnostics; -} - -Tokenizer::~Tokenizer() -{ - destroyScanner(); -} - -bool Tokenizer::init(size_t count, const char * const string[], const int length[]) -{ - if ((count > 0) && (string == 0)) - return false; - - mContext.input = Input(count, string, length); - return initScanner(); -} - -void Tokenizer::setFileNumber(int file) -{ - // We use column number as file number. - // See macro yyfileno. - yyset_column(file, mHandle); -} - -void Tokenizer::setLineNumber(int line) -{ - yyset_lineno(line, mHandle); -} - -void Tokenizer::setMaxTokenSize(size_t maxTokenSize) -{ - mMaxTokenSize = maxTokenSize; -} - -void Tokenizer::lex(Token *token) -{ - int tokenType = yylex(&token->text, &token->location, mHandle); - - if (tokenType == Token::GOT_ERROR) - { - mContext.diagnostics->report(Diagnostics::PP_TOKENIZER_ERROR, token->location, token->text); - token->type = Token::LAST; - } - else - { - token->type = tokenType; - } - - if (token->text.size() > mMaxTokenSize) - { - mContext.diagnostics->report(Diagnostics::PP_TOKEN_TOO_LONG, - token->location, token->text); - token->text.erase(mMaxTokenSize); - } - - token->flags = 0; - - token->setAtStartOfLine(mContext.lineStart); - mContext.lineStart = token->type == '\n'; - - token->setHasLeadingSpace(mContext.leadingSpace); - mContext.leadingSpace = false; -} - -bool Tokenizer::initScanner() -{ - if ((mHandle == nullptr) && yylex_init_extra(&mContext, &mHandle)) - return false; - - yyrestart(0, mHandle); - return true; -} - -void Tokenizer::destroyScanner() -{ - if (mHandle == nullptr) - return; - - yylex_destroy(mHandle); - mHandle = nullptr; -} - -} // namespace pp - diff --git a/src/3rdparty/angle/src/compiler/preprocessor/numeric_lex.h b/src/3rdparty/angle/src/compiler/preprocessor/numeric_lex.h deleted file mode 100644 index 6ea779ab8f..0000000000 --- a/src/3rdparty/angle/src/compiler/preprocessor/numeric_lex.h +++ /dev/null @@ -1,72 +0,0 @@ -// -// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// - -// numeric_lex.h: Functions to extract numeric values from string. - -#ifndef COMPILER_PREPROCESSOR_NUMERICLEX_H_ -#define COMPILER_PREPROCESSOR_NUMERICLEX_H_ - -#include <cmath> -#include <sstream> - -namespace pp -{ - -inline std::ios::fmtflags numeric_base_int(const std::string &str) -{ - if ((str.size() >= 2) && (str[0] == '0') && (str[1] == 'x' || str[1] == 'X')) - { - return std::ios::hex; - } - if ((str.size() >= 1) && (str[0] == '0')) - { - return std::ios::oct; - } - return std::ios::dec; -} - -// The following functions parse the given string to extract a numerical -// value of the given type. These functions assume that the string is -// of the correct form. They can only fail if the parsed value is too big, -// in which case false is returned. - -template <typename IntType> -bool numeric_lex_int(const std::string &str, IntType *value) -{ - std::istringstream stream(str); - // This should not be necessary, but MSVS has a buggy implementation. - // It returns incorrect results if the base is not specified. - stream.setf(numeric_base_int(str), std::ios::basefield); - - stream >> (*value); - return !stream.fail(); -} - -template <typename FloatType> -bool numeric_lex_float(const std::string &str, FloatType *value) -{ -// On 64-bit Intel Android, istringstream is broken. Until this is fixed in -// a newer NDK, don't use it. Android doesn't have locale support, so this -// doesn't have to force the C locale. -// TODO(thakis): Remove this once this bug has been fixed in the NDK and -// that NDK has been rolled into chromium. -#if defined(ANGLE_PLATFORM_ANDROID) && __x86_64__ - *value = strtod(str.c_str(), nullptr); - return errno != ERANGE; -#else - std::istringstream stream(str); - // Force "C" locale so that decimal character is always '.', and - // not dependent on the current locale. - stream.imbue(std::locale::classic()); - - stream >> (*value); - return !stream.fail() && std::isfinite(*value); -#endif -} - -} // namespace pp. - -#endif // COMPILER_PREPROCESSOR_NUMERICLEX_H_ |