Add const
qualifier support for function arguments in shaders
This prevents the function argument from being reassigned within the function. Example: void test(const int t) {}
This commit is contained in:
parent
4a29f657b6
commit
d7d35e4f73
@ -64,6 +64,13 @@ static String _prestr(SL::DataPrecision p_pres) {
|
|||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static String _constr(bool p_is_const) {
|
||||||
|
if (p_is_const) {
|
||||||
|
return "const ";
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
static String _qualstr(SL::ArgumentQualifier p_qual) {
|
static String _qualstr(SL::ArgumentQualifier p_qual) {
|
||||||
switch (p_qual) {
|
switch (p_qual) {
|
||||||
case SL::ARGUMENT_QUALIFIER_IN:
|
case SL::ARGUMENT_QUALIFIER_IN:
|
||||||
@ -254,6 +261,8 @@ void ShaderCompilerGLES2::_dump_function_deps(const SL::ShaderNode *p_node, cons
|
|||||||
header += ", ";
|
header += ", ";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
header += _constr(fnode->arguments[i].is_const);
|
||||||
|
|
||||||
if (fnode->arguments[i].type == SL::TYPE_STRUCT) {
|
if (fnode->arguments[i].type == SL::TYPE_STRUCT) {
|
||||||
header += _qualstr(fnode->arguments[i].qualifier) + _mkid(fnode->arguments[i].type_str) + " " + _mkid(fnode->arguments[i].name);
|
header += _qualstr(fnode->arguments[i].qualifier) + _mkid(fnode->arguments[i].type_str) + " " + _mkid(fnode->arguments[i].name);
|
||||||
} else {
|
} else {
|
||||||
@ -425,7 +434,7 @@ String ShaderCompilerGLES2::_dump_node_code(const SL::Node *p_node, int p_level,
|
|||||||
|
|
||||||
for (int i = 0; i < snode->vconstants.size(); i++) {
|
for (int i = 0; i < snode->vconstants.size(); i++) {
|
||||||
String gcode;
|
String gcode;
|
||||||
gcode += "const ";
|
gcode += _constr(true);
|
||||||
if (snode->vconstants[i].type == SL::TYPE_STRUCT) {
|
if (snode->vconstants[i].type == SL::TYPE_STRUCT) {
|
||||||
gcode += _mkid(snode->vconstants[i].type_str);
|
gcode += _mkid(snode->vconstants[i].type_str);
|
||||||
} else {
|
} else {
|
||||||
@ -517,9 +526,7 @@ String ShaderCompilerGLES2::_dump_node_code(const SL::Node *p_node, int p_level,
|
|||||||
SL::VariableDeclarationNode *var_dec_node = (SL::VariableDeclarationNode *)p_node;
|
SL::VariableDeclarationNode *var_dec_node = (SL::VariableDeclarationNode *)p_node;
|
||||||
|
|
||||||
StringBuffer<> declaration;
|
StringBuffer<> declaration;
|
||||||
if (var_dec_node->is_const) {
|
declaration += _constr(var_dec_node->is_const);
|
||||||
declaration += "const ";
|
|
||||||
}
|
|
||||||
if (var_dec_node->datatype == SL::TYPE_STRUCT) {
|
if (var_dec_node->datatype == SL::TYPE_STRUCT) {
|
||||||
declaration += _mkid(var_dec_node->struct_name);
|
declaration += _mkid(var_dec_node->struct_name);
|
||||||
} else {
|
} else {
|
||||||
|
@ -213,6 +213,13 @@ static String _prestr(SL::DataPrecision p_pres) {
|
|||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static String _constr(bool p_is_const) {
|
||||||
|
if (p_is_const) {
|
||||||
|
return "const ";
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
static String _qualstr(SL::ArgumentQualifier p_qual) {
|
static String _qualstr(SL::ArgumentQualifier p_qual) {
|
||||||
switch (p_qual) {
|
switch (p_qual) {
|
||||||
case SL::ARGUMENT_QUALIFIER_IN:
|
case SL::ARGUMENT_QUALIFIER_IN:
|
||||||
@ -373,6 +380,9 @@ void ShaderCompilerGLES3::_dump_function_deps(const SL::ShaderNode *p_node, cons
|
|||||||
if (i > 0) {
|
if (i > 0) {
|
||||||
header += ", ";
|
header += ", ";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
header += _constr(fnode->arguments[i].is_const);
|
||||||
|
|
||||||
if (fnode->arguments[i].type == SL::TYPE_STRUCT) {
|
if (fnode->arguments[i].type == SL::TYPE_STRUCT) {
|
||||||
header += _qualstr(fnode->arguments[i].qualifier) + _mkid(fnode->arguments[i].type_str) + " " + _mkid(fnode->arguments[i].name);
|
header += _qualstr(fnode->arguments[i].qualifier) + _mkid(fnode->arguments[i].type_str) + " " + _mkid(fnode->arguments[i].name);
|
||||||
} else {
|
} else {
|
||||||
@ -562,7 +572,7 @@ String ShaderCompilerGLES3::_dump_node_code(const SL::Node *p_node, int p_level,
|
|||||||
for (int i = 0; i < pnode->vconstants.size(); i++) {
|
for (int i = 0; i < pnode->vconstants.size(); i++) {
|
||||||
const SL::ShaderNode::Constant &cnode = pnode->vconstants[i];
|
const SL::ShaderNode::Constant &cnode = pnode->vconstants[i];
|
||||||
String gcode;
|
String gcode;
|
||||||
gcode += "const ";
|
gcode += _constr(true);
|
||||||
if (pnode->vconstants[i].type == SL::TYPE_STRUCT) {
|
if (pnode->vconstants[i].type == SL::TYPE_STRUCT) {
|
||||||
gcode += _mkid(cnode.type_str);
|
gcode += _mkid(cnode.type_str);
|
||||||
} else {
|
} else {
|
||||||
@ -655,9 +665,7 @@ String ShaderCompilerGLES3::_dump_node_code(const SL::Node *p_node, int p_level,
|
|||||||
SL::VariableDeclarationNode *vdnode = (SL::VariableDeclarationNode *)p_node;
|
SL::VariableDeclarationNode *vdnode = (SL::VariableDeclarationNode *)p_node;
|
||||||
|
|
||||||
String declaration;
|
String declaration;
|
||||||
if (vdnode->is_const) {
|
declaration += _constr(vdnode->is_const);
|
||||||
declaration += "const ";
|
|
||||||
}
|
|
||||||
if (vdnode->datatype == SL::TYPE_STRUCT) {
|
if (vdnode->datatype == SL::TYPE_STRUCT) {
|
||||||
declaration += _mkid(vdnode->struct_name);
|
declaration += _mkid(vdnode->struct_name);
|
||||||
} else {
|
} else {
|
||||||
|
@ -953,6 +953,9 @@ bool ShaderLanguage::_find_identifier(const BlockNode *p_block, const Map<String
|
|||||||
if (r_struct_name) {
|
if (r_struct_name) {
|
||||||
*r_struct_name = function->arguments[i].type_str;
|
*r_struct_name = function->arguments[i].type_str;
|
||||||
}
|
}
|
||||||
|
if (r_is_const) {
|
||||||
|
*r_is_const = function->arguments[i].is_const;
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3436,11 +3439,13 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
|
|||||||
for (int i = 0; i < call_function->arguments.size(); i++) {
|
for (int i = 0; i < call_function->arguments.size(); i++) {
|
||||||
int argidx = i + 1;
|
int argidx = i + 1;
|
||||||
if (argidx < func->arguments.size()) {
|
if (argidx < func->arguments.size()) {
|
||||||
if (call_function->arguments[i].qualifier == ArgumentQualifier::ARGUMENT_QUALIFIER_OUT || call_function->arguments[i].qualifier == ArgumentQualifier::ARGUMENT_QUALIFIER_INOUT) {
|
if (call_function->arguments[i].is_const || call_function->arguments[i].qualifier == ArgumentQualifier::ARGUMENT_QUALIFIER_OUT || call_function->arguments[i].qualifier == ArgumentQualifier::ARGUMENT_QUALIFIER_INOUT) {
|
||||||
bool error = false;
|
bool error = false;
|
||||||
Node *n = func->arguments[argidx];
|
Node *n = func->arguments[argidx];
|
||||||
if (n->type == Node::TYPE_CONSTANT || n->type == Node::TYPE_OPERATOR) {
|
if (n->type == Node::TYPE_CONSTANT || n->type == Node::TYPE_OPERATOR) {
|
||||||
error = true;
|
if (!call_function->arguments[i].is_const) {
|
||||||
|
error = true;
|
||||||
|
}
|
||||||
} else if (n->type == Node::TYPE_ARRAY) {
|
} else if (n->type == Node::TYPE_ARRAY) {
|
||||||
ArrayNode *an = static_cast<ArrayNode *>(n);
|
ArrayNode *an = static_cast<ArrayNode *>(n);
|
||||||
if (an->call_expression != nullptr || an->is_const) {
|
if (an->call_expression != nullptr || an->is_const) {
|
||||||
@ -6482,15 +6487,29 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool is_const = false;
|
||||||
|
if (tk.type == TK_CONST) {
|
||||||
|
is_const = true;
|
||||||
|
tk = _get_token();
|
||||||
|
}
|
||||||
|
|
||||||
ArgumentQualifier qualifier = ARGUMENT_QUALIFIER_IN;
|
ArgumentQualifier qualifier = ARGUMENT_QUALIFIER_IN;
|
||||||
|
|
||||||
if (tk.type == TK_ARG_IN) {
|
if (tk.type == TK_ARG_IN) {
|
||||||
qualifier = ARGUMENT_QUALIFIER_IN;
|
qualifier = ARGUMENT_QUALIFIER_IN;
|
||||||
tk = _get_token();
|
tk = _get_token();
|
||||||
} else if (tk.type == TK_ARG_OUT) {
|
} else if (tk.type == TK_ARG_OUT) {
|
||||||
|
if (is_const) {
|
||||||
|
_set_error("'out' qualifier cannot be used within a function parameter declared with 'const'.");
|
||||||
|
return ERR_PARSE_ERROR;
|
||||||
|
}
|
||||||
qualifier = ARGUMENT_QUALIFIER_OUT;
|
qualifier = ARGUMENT_QUALIFIER_OUT;
|
||||||
tk = _get_token();
|
tk = _get_token();
|
||||||
} else if (tk.type == TK_ARG_INOUT) {
|
} else if (tk.type == TK_ARG_INOUT) {
|
||||||
|
if (is_const) {
|
||||||
|
_set_error("'inout' qualifier cannot be used within a function parameter declared with 'const'.");
|
||||||
|
return ERR_PARSE_ERROR;
|
||||||
|
}
|
||||||
qualifier = ARGUMENT_QUALIFIER_INOUT;
|
qualifier = ARGUMENT_QUALIFIER_INOUT;
|
||||||
tk = _get_token();
|
tk = _get_token();
|
||||||
}
|
}
|
||||||
@ -6568,6 +6587,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
|
|||||||
arg.type_str = param_struct_name;
|
arg.type_str = param_struct_name;
|
||||||
arg.precision = pprecision;
|
arg.precision = pprecision;
|
||||||
arg.qualifier = qualifier;
|
arg.qualifier = qualifier;
|
||||||
|
arg.is_const = is_const;
|
||||||
|
|
||||||
func_node->arguments.push_back(arg);
|
func_node->arguments.push_back(arg);
|
||||||
|
|
||||||
@ -6977,6 +6997,10 @@ Error ShaderLanguage::complete(const String &p_code, const Map<StringName, Funct
|
|||||||
if (j == completion_argument) {
|
if (j == completion_argument) {
|
||||||
calltip += CharType(0xFFFF);
|
calltip += CharType(0xFFFF);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (shader->functions[i].function->arguments[j].is_const) {
|
||||||
|
calltip += "const ";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (shader->functions[i].function->arguments.size()) {
|
if (shader->functions[i].function->arguments.size()) {
|
||||||
|
@ -554,6 +554,7 @@ public:
|
|||||||
DataType type;
|
DataType type;
|
||||||
StringName type_str;
|
StringName type_str;
|
||||||
DataPrecision precision;
|
DataPrecision precision;
|
||||||
|
bool is_const;
|
||||||
};
|
};
|
||||||
|
|
||||||
StringName name;
|
StringName name;
|
||||||
|
Loading…
Reference in New Issue
Block a user