| 1507 | } |
| 1508 | |
| 1509 | bool reshadefx::parser::parse_variable(type type, std::string name, bool global) |
| 1510 | { |
| 1511 | const location variable_location = std::move(_token.location); |
| 1512 | |
| 1513 | if (type.is_void()) |
| 1514 | { |
| 1515 | error(variable_location, 3038, '\'' + name + "': variables cannot be void"); |
| 1516 | return false; |
| 1517 | } |
| 1518 | if (type.has(type::q_in) || type.has(type::q_out)) |
| 1519 | { |
| 1520 | error(variable_location, 3055, '\'' + name + "': variables cannot be declared 'in' or 'out'"); |
| 1521 | return false; |
| 1522 | } |
| 1523 | |
| 1524 | // Local and global variables have different requirements |
| 1525 | if (global) |
| 1526 | { |
| 1527 | // Check that type qualifier combinations are valid |
| 1528 | if (type.has(type::q_static)) |
| 1529 | { |
| 1530 | // Global variables that are 'static' cannot be of another storage class |
| 1531 | if (type.has(type::q_uniform)) |
| 1532 | { |
| 1533 | error(variable_location, 3007, '\'' + name + "': uniform global variables cannot be declared 'static'"); |
| 1534 | return false; |
| 1535 | } |
| 1536 | // The 'volatile' qualifier is only valid memory object declarations that are storage images or uniform blocks |
| 1537 | if (type.has(type::q_volatile)) |
| 1538 | { |
| 1539 | error(variable_location, 3008, '\'' + name + "': global variables cannot be declared 'volatile'"); |
| 1540 | return false; |
| 1541 | } |
| 1542 | } |
| 1543 | else if (!type.has(type::q_groupshared)) |
| 1544 | { |
| 1545 | // Make all global variables 'uniform' by default, since they should be externally visible without the 'static' keyword |
| 1546 | if (!type.has(type::q_uniform) && !type.is_object()) |
| 1547 | warning(variable_location, 5000, '\'' + name + "': global variables are considered 'uniform' by default"); |
| 1548 | |
| 1549 | // Global variables that are not 'static' are always 'extern' and 'uniform' |
| 1550 | type.qualifiers |= type::q_extern | type::q_uniform; |
| 1551 | |
| 1552 | // It is invalid to make 'uniform' variables constant, since they can be modified externally |
| 1553 | if (type.has(type::q_const)) |
| 1554 | { |
| 1555 | error(variable_location, 3035, '\'' + name + "': variables which are 'uniform' cannot be declared 'const'"); |
| 1556 | return false; |
| 1557 | } |
| 1558 | } |
| 1559 | } |
| 1560 | else |
| 1561 | { |
| 1562 | // Static does not really have meaning on local variables |
| 1563 | if (type.has(type::q_static)) |
| 1564 | type.qualifiers &= ~type::q_static; |
| 1565 | |
| 1566 | if (type.has(type::q_extern)) |
nothing calls this directly
no test coverage detected