diff --git a/include/Nazara/Shader/ShaderLangErrors.hpp b/include/Nazara/Shader/ShaderLangErrors.hpp index 24aeaa557..6020534ee 100644 --- a/include/Nazara/Shader/ShaderLangErrors.hpp +++ b/include/Nazara/Shader/ShaderLangErrors.hpp @@ -36,7 +36,7 @@ namespace Nz::ShaderLang #include }; - class Error : public std::exception + class NAZARA_SHADER_API Error : public std::exception { public: inline Error(SourceLocation sourceLocation, ErrorCategory errorCategory, ErrorType errorType) noexcept; diff --git a/src/Nazara/Shader/Ast/SanitizeVisitor.cpp b/src/Nazara/Shader/Ast/SanitizeVisitor.cpp index 18b70eb6e..6500f85d1 100644 --- a/src/Nazara/Shader/Ast/SanitizeVisitor.cpp +++ b/src/Nazara/Shader/Ast/SanitizeVisitor.cpp @@ -45,7 +45,7 @@ namespace Nz::ShaderAst { if (index < availableIndices.GetSize()) { - if (!availableIndices.Test(index)) + if (!availableIndices.Test(index) && !preregisteredIndices.UnboundedTest(index)) throw ShaderLang::AstAlreadyUsedIndexPreregisterError{ sourceLocation, index }; } else if (index >= availableIndices.GetSize()) @@ -1258,16 +1258,16 @@ namespace Nz::ShaderAst { if (member.cond.HasValue()) { - ComputeExprValue(member.cond, node.sourceLocation); + ComputeExprValue(member.cond, member.sourceLocation); if (member.cond.IsResultingValue() && !member.cond.GetResultingValue()) continue; } if (member.builtin.HasValue()) - ComputeExprValue(member.builtin, node.sourceLocation); + ComputeExprValue(member.builtin, member.sourceLocation); if (member.locationIndex.HasValue()) - ComputeExprValue(member.locationIndex, node.sourceLocation); + ComputeExprValue(member.locationIndex, member.sourceLocation); if (member.builtin.HasValue() && member.locationIndex.HasValue()) throw ShaderLang::CompilerStructFieldBuiltinLocationError{ member.sourceLocation }; @@ -2097,7 +2097,9 @@ namespace Nz::ShaderAst if (attribute.IsExpression()) { - std::optional value = ComputeConstantValue(*attribute.GetExpression()); + auto& expr = *attribute.GetExpression(); + + std::optional value = ComputeConstantValue(expr); if (!value) return ValidationResult::Unresolved; @@ -2109,13 +2111,13 @@ namespace Nz::ShaderAst if (std::holds_alternative(*value) && std::is_same_v) attribute = static_cast(std::get(*value)); else - throw ShaderLang::CompilerAttributeUnexpectedTypeError{ sourceLocation }; + throw ShaderLang::CompilerAttributeUnexpectedTypeError{ expr.sourceLocation }; } else attribute = std::get(*value); } else - throw ShaderLang::CompilerAttributeUnexpectedExpressionError{ sourceLocation }; + throw ShaderLang::CompilerAttributeUnexpectedExpressionError{ expr.sourceLocation }; } return ValidationResult::Validated; @@ -2129,6 +2131,8 @@ namespace Nz::ShaderAst if (attribute.IsExpression()) { + auto& expr = *attribute.GetExpression(); + std::optional value = ComputeConstantValue(*attribute.GetExpression()); if (!value) { @@ -2144,13 +2148,13 @@ namespace Nz::ShaderAst if (std::holds_alternative(*value) && std::is_same_v) targetAttribute = static_cast(std::get(*value)); else - throw ShaderLang::CompilerAttributeUnexpectedTypeError{ sourceLocation }; + throw ShaderLang::CompilerAttributeUnexpectedTypeError{ expr.sourceLocation }; } else targetAttribute = std::get(*value); } else - throw ShaderLang::CompilerAttributeUnexpectedExpressionError{ sourceLocation }; + throw ShaderLang::CompilerAttributeUnexpectedExpressionError{ expr.sourceLocation }; } else { diff --git a/src/Nazara/Shader/ShaderLangLexer.cpp b/src/Nazara/Shader/ShaderLangLexer.cpp index 03f077dc1..1f6f0834c 100644 --- a/src/Nazara/Shader/ShaderLangLexer.cpp +++ b/src/Nazara/Shader/ShaderLangLexer.cpp @@ -81,9 +81,15 @@ namespace Nz::ShaderLang }; UInt32 currentLine = 1; - std::size_t lastLineFeed = 0; + std::size_t lineStartPos = 0; std::vector tokens; + auto HandleNewLine = [&] + { + currentLine++; + lineStartPos = currentPos + 1; + }; + std::shared_ptr currentFile; if (!filePath.empty()) currentFile = std::make_shared(filePath); @@ -93,7 +99,7 @@ namespace Nz::ShaderLang char c = Peek(0); Token token; - token.location.startColumn = SafeCast(currentPos - lastLineFeed) + 1; + token.location.startColumn = SafeCast(currentPos - lineStartPos) + 1; token.location.startLine = currentLine; token.location.file = currentFile; @@ -113,11 +119,8 @@ namespace Nz::ShaderLang break; //< Ignore blank spaces case '\n': - { - currentLine++; - lastLineFeed = currentPos; + HandleNewLine(); break; - } case '-': { @@ -170,10 +173,7 @@ namespace Nz::ShaderLang } } else if (next == '\n') - { - currentLine++; - lastLineFeed = currentPos + 1; - } + HandleNewLine(); } while (next != -1); } @@ -225,7 +225,7 @@ namespace Nz::ShaderLang currentPos++; } - token.location.endColumn = SafeCast(currentPos - lastLineFeed) + 1; + token.location.endColumn = SafeCast(currentPos - lineStartPos) + 1; token.location.endLine = currentLine; if (floatingPoint) @@ -417,7 +417,7 @@ namespace Nz::ShaderLang case '\0': case '\n': case '\r': - token.location.endColumn = SafeCast(currentPos - lastLineFeed) + 1; + token.location.endColumn = SafeCast(currentPos - lineStartPos) + 1; token.location.endLine = currentLine; throw LexerUnfinishedStringError{ token.location }; @@ -433,7 +433,7 @@ namespace Nz::ShaderLang case '"': character = '"'; break; case '\\': character = '\\'; break; default: - token.location.endColumn = SafeCast(currentPos - lastLineFeed) + 1; + token.location.endColumn = SafeCast(currentPos - lineStartPos) + 1; token.location.endLine = currentLine; throw LexerUnrecognizedCharError{ token.location }; } @@ -476,7 +476,7 @@ namespace Nz::ShaderLang } else { - token.location.endColumn = SafeCast(currentPos - lastLineFeed) + 1; + token.location.endColumn = SafeCast(currentPos - lineStartPos) + 1; token.location.endLine = currentLine; throw LexerUnrecognizedTokenError{ token.location }; } @@ -485,7 +485,7 @@ namespace Nz::ShaderLang if (tokenType) { - token.location.endColumn = SafeCast(currentPos - lastLineFeed) + 1; + token.location.endColumn = SafeCast(currentPos - lineStartPos) + 1; token.location.endLine = currentLine; token.type = *tokenType; diff --git a/src/Nazara/Shader/ShaderLangParser.cpp b/src/Nazara/Shader/ShaderLangParser.cpp index 617961cf3..f34a82838 100644 --- a/src/Nazara/Shader/ShaderLangParser.cpp +++ b/src/Nazara/Shader/ShaderLangParser.cpp @@ -1195,8 +1195,10 @@ namespace Nz::ShaderLang // Function call SourceLocation closingLocation; auto parameters = ParseExpressionList(TokenType::ClosingParenthesis, &closingLocation); + + const SourceLocation& lhsLoc = lhs->sourceLocation; lhs = ShaderBuilder::CallFunction(std::move(lhs), std::move(parameters)); - lhs->sourceLocation = SourceLocation::BuildFromTo(token.location, closingLocation); + lhs->sourceLocation = SourceLocation::BuildFromTo(lhsLoc, closingLocation); continue; } @@ -1208,8 +1210,9 @@ namespace Nz::ShaderLang SourceLocation closingLocation; auto parameters = ParseExpressionList(TokenType::ClosingSquareBracket, &closingLocation); + const SourceLocation& lhsLoc = lhs->sourceLocation; lhs = ShaderBuilder::AccessIndex(std::move(lhs), std::move(parameters)); - lhs->sourceLocation = SourceLocation::BuildFromTo(token.location, closingLocation); + lhs->sourceLocation = SourceLocation::BuildFromTo(lhsLoc, closingLocation); continue; } diff --git a/xmake.lua b/xmake.lua index e0dd2b1d8..8650fbda9 100644 --- a/xmake.lua +++ b/xmake.lua @@ -184,6 +184,7 @@ if is_plat("windows") then add_cxxflags("/bigobj", "/permissive-", "/Zc:__cplusplus", "/Zc:externConstexpr", "/Zc:inline", "/Zc:lambda", "/Zc:preprocessor", "/Zc:referenceBinding", "/Zc:strictStrings", "/Zc:throwingNew") add_cxflags("/w44062") -- Enable warning: switch case not handled add_cxflags("/wd4251") -- Disable warning: class needs to have dll-interface to be used by clients of class blah blah blah + add_cxflags("/wd4275") -- Disable warning: DLL-interface class 'class_1' used as base for DLL-interface blah elseif is_plat("mingw") then add_cxflags("-Og", "-Wa,-mbig-obj") add_ldflags("-Wa,-mbig-obj")