Fix many asan and ubsan reported issues

This allows most demos to run without any ubsan or asan errors. There
are still some things in thirdpart/ and some things in AudioServer that
needs a look but this fixes a lot of issues. This should help debug less
obvious issues, hopefully.

This fixes #25217 and fixes #25218
This commit is contained in:
Hein-Pieter van Braam 2019-01-30 02:12:41 +01:00
parent 35bb52011a
commit d308eb091a
16 changed files with 198 additions and 131 deletions

View file

@ -37,7 +37,11 @@ struct Pair {
F first; F first;
S second; S second;
Pair() {} Pair() :
first(),
second() {
}
Pair(F p_first, const S &p_second) : Pair(F p_first, const S &p_second) :
first(p_first), first(p_first),
second(p_second) { second(p_second) {

View file

@ -2816,27 +2816,37 @@ uint32_t Variant::hash() const {
const PoolVector<uint8_t> &arr = *reinterpret_cast<const PoolVector<uint8_t> *>(_data._mem); const PoolVector<uint8_t> &arr = *reinterpret_cast<const PoolVector<uint8_t> *>(_data._mem);
int len = arr.size(); int len = arr.size();
PoolVector<uint8_t>::Read r = arr.read(); if (likely(len)) {
PoolVector<uint8_t>::Read r = arr.read();
return hash_djb2_buffer((uint8_t *)&r[0], len); return hash_djb2_buffer((uint8_t *)&r[0], len);
} else {
return hash_djb2_one_64(0);
}
} break; } break;
case POOL_INT_ARRAY: { case POOL_INT_ARRAY: {
const PoolVector<int> &arr = *reinterpret_cast<const PoolVector<int> *>(_data._mem); const PoolVector<int> &arr = *reinterpret_cast<const PoolVector<int> *>(_data._mem);
int len = arr.size(); int len = arr.size();
PoolVector<int>::Read r = arr.read(); if (likely(len)) {
PoolVector<int>::Read r = arr.read();
return hash_djb2_buffer((uint8_t *)&r[0], len * sizeof(int)); return hash_djb2_buffer((uint8_t *)&r[0], len * sizeof(int));
} else {
return hash_djb2_one_64(0);
}
} break; } break;
case POOL_REAL_ARRAY: { case POOL_REAL_ARRAY: {
const PoolVector<real_t> &arr = *reinterpret_cast<const PoolVector<real_t> *>(_data._mem); const PoolVector<real_t> &arr = *reinterpret_cast<const PoolVector<real_t> *>(_data._mem);
int len = arr.size(); int len = arr.size();
PoolVector<real_t>::Read r = arr.read();
return hash_djb2_buffer((uint8_t *)&r[0], len * sizeof(real_t)); if (likely(len)) {
PoolVector<real_t>::Read r = arr.read();
return hash_djb2_buffer((uint8_t *)&r[0], len * sizeof(real_t));
} else {
return hash_djb2_one_float(0.0);
}
} break; } break;
case POOL_STRING_ARRAY: { case POOL_STRING_ARRAY: {
@ -2844,10 +2854,13 @@ uint32_t Variant::hash() const {
uint32_t hash = 5831; uint32_t hash = 5831;
const PoolVector<String> &arr = *reinterpret_cast<const PoolVector<String> *>(_data._mem); const PoolVector<String> &arr = *reinterpret_cast<const PoolVector<String> *>(_data._mem);
int len = arr.size(); int len = arr.size();
PoolVector<String>::Read r = arr.read();
for (int i = 0; i < len; i++) { if (likely(len)) {
hash = hash_djb2_one_32(r[i].hash(), hash); PoolVector<String>::Read r = arr.read();
for (int i = 0; i < len; i++) {
hash = hash_djb2_one_32(r[i].hash(), hash);
}
} }
return hash; return hash;
@ -2857,48 +2870,54 @@ uint32_t Variant::hash() const {
uint32_t hash = 5831; uint32_t hash = 5831;
const PoolVector<Vector2> &arr = *reinterpret_cast<const PoolVector<Vector2> *>(_data._mem); const PoolVector<Vector2> &arr = *reinterpret_cast<const PoolVector<Vector2> *>(_data._mem);
int len = arr.size(); int len = arr.size();
PoolVector<Vector2>::Read r = arr.read();
for (int i = 0; i < len; i++) { if (likely(len)) {
hash = hash_djb2_one_float(r[i].x, hash); PoolVector<Vector2>::Read r = arr.read();
hash = hash_djb2_one_float(r[i].y, hash);
for (int i = 0; i < len; i++) {
hash = hash_djb2_one_float(r[i].x, hash);
hash = hash_djb2_one_float(r[i].y, hash);
}
} }
return hash; return hash;
} break; } break;
case POOL_VECTOR3_ARRAY: { case POOL_VECTOR3_ARRAY: {
uint32_t hash = 5831; uint32_t hash = 5831;
const PoolVector<Vector3> &arr = *reinterpret_cast<const PoolVector<Vector3> *>(_data._mem); const PoolVector<Vector3> &arr = *reinterpret_cast<const PoolVector<Vector3> *>(_data._mem);
int len = arr.size(); int len = arr.size();
PoolVector<Vector3>::Read r = arr.read();
for (int i = 0; i < len; i++) { if (likely(len)) {
hash = hash_djb2_one_float(r[i].x, hash); PoolVector<Vector3>::Read r = arr.read();
hash = hash_djb2_one_float(r[i].y, hash);
hash = hash_djb2_one_float(r[i].z, hash); for (int i = 0; i < len; i++) {
hash = hash_djb2_one_float(r[i].x, hash);
hash = hash_djb2_one_float(r[i].y, hash);
hash = hash_djb2_one_float(r[i].z, hash);
}
} }
return hash; return hash;
} break; } break;
case POOL_COLOR_ARRAY: { case POOL_COLOR_ARRAY: {
uint32_t hash = 5831; uint32_t hash = 5831;
const PoolVector<Color> &arr = *reinterpret_cast<const PoolVector<Color> *>(_data._mem); const PoolVector<Color> &arr = *reinterpret_cast<const PoolVector<Color> *>(_data._mem);
int len = arr.size(); int len = arr.size();
PoolVector<Color>::Read r = arr.read();
for (int i = 0; i < len; i++) { if (likely(len)) {
hash = hash_djb2_one_float(r[i].r, hash); PoolVector<Color>::Read r = arr.read();
hash = hash_djb2_one_float(r[i].g, hash);
hash = hash_djb2_one_float(r[i].b, hash); for (int i = 0; i < len; i++) {
hash = hash_djb2_one_float(r[i].a, hash); hash = hash_djb2_one_float(r[i].r, hash);
hash = hash_djb2_one_float(r[i].g, hash);
hash = hash_djb2_one_float(r[i].b, hash);
hash = hash_djb2_one_float(r[i].a, hash);
}
} }
return hash; return hash;
} break; } break;
default: {} default: {}
} }

View file

@ -318,7 +318,7 @@ String ShaderCompilerGLES2::_dump_node_code(SL::Node *p_node, int p_level, Gener
uniform_code += "uniform "; uniform_code += "uniform ";
uniform_code += _prestr(E->get().precission); uniform_code += _prestr(E->get().precision);
uniform_code += _typestr(E->get().type); uniform_code += _typestr(E->get().type);
uniform_code += " "; uniform_code += " ";
uniform_code += _mkid(E->key()); uniform_code += _mkid(E->key());
@ -344,7 +344,7 @@ String ShaderCompilerGLES2::_dump_node_code(SL::Node *p_node, int p_level, Gener
StringBuffer<> varying_code; StringBuffer<> varying_code;
varying_code += "varying "; varying_code += "varying ";
varying_code += _prestr(E->get().precission); varying_code += _prestr(E->get().precision);
varying_code += _typestr(E->get().type); varying_code += _typestr(E->get().type);
varying_code += " "; varying_code += " ";
varying_code += _mkid(E->key()); varying_code += _mkid(E->key());

View file

@ -373,7 +373,7 @@ String ShaderCompilerGLES3::_dump_node_code(SL::Node *p_node, int p_level, Gener
ucode = "uniform "; ucode = "uniform ";
} }
ucode += _prestr(E->get().precission); ucode += _prestr(E->get().precision);
ucode += _typestr(E->get().type); ucode += _typestr(E->get().type);
ucode += " " + _mkid(E->key()); ucode += " " + _mkid(E->key());
ucode += ";\n"; ucode += ";\n";
@ -464,7 +464,7 @@ String ShaderCompilerGLES3::_dump_node_code(SL::Node *p_node, int p_level, Gener
String vcode; String vcode;
String interp_mode = _interpstr(E->get().interpolation); String interp_mode = _interpstr(E->get().interpolation);
vcode += _prestr(E->get().precission); vcode += _prestr(E->get().precision);
vcode += _typestr(E->get().type); vcode += _typestr(E->get().type);
vcode += " " + _mkid(E->key()); vcode += " " + _mkid(E->key());
vcode += ";\n"; vcode += ";\n";

View file

@ -110,7 +110,7 @@ static String dump_node_code(SL::Node *p_node, int p_level) {
for (Map<StringName, SL::ShaderNode::Uniform>::Element *E = pnode->uniforms.front(); E; E = E->next()) { for (Map<StringName, SL::ShaderNode::Uniform>::Element *E = pnode->uniforms.front(); E; E = E->next()) {
String ucode = "uniform "; String ucode = "uniform ";
ucode += _prestr(E->get().precission); ucode += _prestr(E->get().precision);
ucode += _typestr(E->get().type); ucode += _typestr(E->get().type);
ucode += " " + String(E->key()); ucode += " " + String(E->key());
@ -137,7 +137,7 @@ static String dump_node_code(SL::Node *p_node, int p_level) {
for (Map<StringName, SL::ShaderNode::Varying>::Element *E = pnode->varyings.front(); E; E = E->next()) { for (Map<StringName, SL::ShaderNode::Varying>::Element *E = pnode->varyings.front(); E; E = E->next()) {
String vcode = "varying "; String vcode = "varying ";
vcode += _prestr(E->get().precission); vcode += _prestr(E->get().precision);
vcode += _typestr(E->get().type); vcode += _typestr(E->get().type);
vcode += " " + String(E->key()); vcode += " " + String(E->key());

View file

@ -69,8 +69,12 @@ void CollisionObjectBullet::ShapeWrapper::claim_bt_shape(const btVector3 &body_s
CollisionObjectBullet::CollisionObjectBullet(Type p_type) : CollisionObjectBullet::CollisionObjectBullet(Type p_type) :
RIDBullet(), RIDBullet(),
type(p_type), type(p_type),
instance_id(0),
collisionLayer(0),
collisionMask(0),
collisionsEnabled(true), collisionsEnabled(true),
m_isStatic(false), m_isStatic(false),
ray_pickable(false),
bt_collision_object(NULL), bt_collision_object(NULL),
body_scale(1., 1., 1.), body_scale(1., 1., 1.),
force_shape_reset(false), force_shape_reset(false),

View file

@ -615,6 +615,9 @@ static GDScriptCompletionIdentifier _type_from_gdtype(const GDScriptDataType &p_
ci.type.script_type = p_gdtype.script_type; ci.type.script_type = p_gdtype.script_type;
switch (p_gdtype.kind) { switch (p_gdtype.kind) {
case GDScriptDataType::UNINITIALIZED: {
ERR_EXPLAIN("Uninitialized completion. Please report a bug.");
} break;
case GDScriptDataType::BUILTIN: { case GDScriptDataType::BUILTIN: {
ci.type.kind = GDScriptParser::DataType::BUILTIN; ci.type.kind = GDScriptParser::DataType::BUILTIN;
} break; } break;

View file

@ -45,10 +45,11 @@ class GDScript;
struct GDScriptDataType { struct GDScriptDataType {
bool has_type; bool has_type;
enum { enum {
UNINITIALIZED,
BUILTIN, BUILTIN,
NATIVE, NATIVE,
SCRIPT, SCRIPT,
GDSCRIPT GDSCRIPT,
} kind; } kind;
Variant::Type builtin_type; Variant::Type builtin_type;
StringName native_type; StringName native_type;
@ -58,6 +59,8 @@ struct GDScriptDataType {
if (!has_type) return true; // Can't type check if (!has_type) return true; // Can't type check
switch (kind) { switch (kind) {
case UNINITIALIZED:
break;
case BUILTIN: { case BUILTIN: {
Variant::Type var_type = p_variant.get_type(); Variant::Type var_type = p_variant.get_type();
bool valid = builtin_type == var_type; bool valid = builtin_type == var_type;
@ -113,6 +116,8 @@ struct GDScriptDataType {
PropertyInfo info; PropertyInfo info;
if (has_type) { if (has_type) {
switch (kind) { switch (kind) {
case UNINITIALIZED:
break;
case BUILTIN: { case BUILTIN: {
info.type = builtin_type; info.type = builtin_type;
} break; } break;
@ -134,7 +139,9 @@ struct GDScriptDataType {
} }
GDScriptDataType() : GDScriptDataType() :
has_type(false) {} has_type(false),
kind(UNINITIALIZED),
builtin_type(Variant::NIL) {}
}; };
class GDScriptFunction { class GDScriptFunction {

View file

@ -4553,6 +4553,7 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
//variale declaration and (eventual) initialization //variale declaration and (eventual) initialization
ClassNode::Member member; ClassNode::Member member;
bool autoexport = tokenizer->get_token(-1) == GDScriptTokenizer::TK_PR_EXPORT; bool autoexport = tokenizer->get_token(-1) == GDScriptTokenizer::TK_PR_EXPORT;
if (current_export.type != Variant::NIL) { if (current_export.type != Variant::NIL) {
member._export = current_export; member._export = current_export;
@ -5594,6 +5595,9 @@ GDScriptParser::DataType GDScriptParser::_type_from_gdtype(const GDScriptDataTyp
result.script_type = p_gdtype.script_type; result.script_type = p_gdtype.script_type;
switch (p_gdtype.kind) { switch (p_gdtype.kind) {
case GDScriptDataType::UNINITIALIZED: {
ERR_EXPLAIN("Uninitialized datatype. Please report a bug.");
} break;
case GDScriptDataType::BUILTIN: { case GDScriptDataType::BUILTIN: {
result.kind = DataType::BUILTIN; result.kind = DataType::BUILTIN;
} break; } break;

View file

@ -95,6 +95,7 @@ public:
} }
DataType() : DataType() :
kind(UNRESOLVED),
has_type(false), has_type(false),
is_constant(false), is_constant(false),
is_meta_type(false), is_meta_type(false),
@ -168,6 +169,7 @@ public:
MultiplayerAPI::RPCMode rpc_mode; MultiplayerAPI::RPCMode rpc_mode;
int usages; int usages;
}; };
struct Constant { struct Constant {
Node *expression; Node *expression;
DataType type; DataType type;

View file

@ -3004,7 +3004,9 @@ bool OS_X11::is_vsync_enabled() const {
*/ */
void OS_X11::set_context(int p_context) { void OS_X11::set_context(int p_context) {
char *config_name = NULL;
XClassHint *classHint = XAllocClassHint(); XClassHint *classHint = XAllocClassHint();
if (classHint) { if (classHint) {
char *wm_class = (char *)"Godot"; char *wm_class = (char *)"Godot";
@ -3015,13 +3017,15 @@ void OS_X11::set_context(int p_context) {
if (p_context == CONTEXT_ENGINE) { if (p_context == CONTEXT_ENGINE) {
classHint->res_name = (char *)"Godot_Engine"; classHint->res_name = (char *)"Godot_Engine";
wm_class = (char *)((String)GLOBAL_GET("application/config/name")).utf8().ptrw(); config_name = strdup((char *)((String)GLOBAL_GET("application/config/name")).utf8().ptrw());
wm_class = config_name;
} }
classHint->res_class = wm_class; classHint->res_class = wm_class;
XSetClassHint(x11_display, x11_window, classHint); XSetClassHint(x11_display, x11_window, classHint);
XFree(classHint); XFree(classHint);
free(config_name);
} }
} }

View file

@ -114,10 +114,12 @@ private:
Variant value_accum; Variant value_accum;
uint64_t accum_pass; uint64_t accum_pass;
Variant capture; Variant capture;
PropertyAnim() {
accum_pass = 0; PropertyAnim() :
object = NULL; owner(NULL),
} special(SP_NONE),
object(NULL),
accum_pass(0) {}
}; };
Map<StringName, PropertyAnim> property_anim; Map<StringName, PropertyAnim> property_anim;
@ -129,25 +131,28 @@ private:
float bezier_accum; float bezier_accum;
Object *object; Object *object;
uint64_t accum_pass; uint64_t accum_pass;
BezierAnim() {
accum_pass = 0; BezierAnim() :
bezier_accum = 0; owner(NULL),
object = NULL; bezier_accum(0.0),
} object(NULL),
accum_pass(0) {}
}; };
Map<StringName, BezierAnim> bezier_anim; Map<StringName, BezierAnim> bezier_anim;
TrackNodeCache() { TrackNodeCache() :
skeleton = NULL; id(0),
spatial = NULL; node(NULL),
node = NULL; spatial(NULL),
accum_pass = 0; node_2d(NULL),
bone_idx = -1; skeleton(NULL),
node_2d = NULL; bone_idx(-1),
audio_playing = false; accum_pass(0),
animation_playing = false; audio_playing(false),
} audio_start(0.0),
audio_len(0.0),
animation_playing(false) {}
}; };
struct TrackNodeCacheKey { struct TrackNodeCacheKey {

View file

@ -109,6 +109,14 @@ private:
Variant value; Variant value;
bool skip; bool skip;
Track() :
id(0),
object(NULL),
spatial(NULL),
skeleton(NULL),
bone_idx(-1),
skip(false) {}
}; };
typedef Map<TrackKey, Track> TrackMap; typedef Map<TrackKey, Track> TrackMap;

View file

@ -1291,7 +1291,14 @@ void Environment::_bind_methods() {
BIND_ENUM_CONSTANT(SSAO_QUALITY_HIGH); BIND_ENUM_CONSTANT(SSAO_QUALITY_HIGH);
} }
Environment::Environment() { Environment::Environment() :
bg_mode(BG_CLEAR_COLOR),
tone_mapper(TONE_MAPPER_LINEAR),
ssao_blur(SSAO_BLUR_DISABLED),
ssao_quality(SSAO_QUALITY_LOW),
glow_blend_mode(GLOW_BLEND_MODE_ADDITIVE),
dof_blur_far_quality(DOF_BLUR_QUALITY_LOW),
dof_blur_near_quality(DOF_BLUR_QUALITY_LOW) {
environment = VS::get_singleton()->environment_create(); environment = VS::get_singleton()->environment_create();

View file

@ -4113,7 +4113,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
uniform.order = uniforms++; uniform.order = uniforms++;
} }
uniform.type = type; uniform.type = type;
uniform.precission = precision; uniform.precision = precision;
//todo parse default value //todo parse default value
@ -4264,7 +4264,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
ShaderNode::Varying varying; ShaderNode::Varying varying;
varying.type = type; varying.type = type;
varying.precission = precision; varying.precision = precision;
varying.interpolation = interpolation; varying.interpolation = interpolation;
shader->varyings[name] = varying; shader->varyings[name] = varying;

View file

@ -42,7 +42,6 @@ class ShaderLanguage {
public: public:
enum TokenType { enum TokenType {
TK_EMPTY, TK_EMPTY,
TK_IDENTIFIER, TK_IDENTIFIER,
TK_TRUE, TK_TRUE,
@ -267,18 +266,15 @@ public:
FLOW_OP_SWITCH, FLOW_OP_SWITCH,
FLOW_OP_CONTINUE, FLOW_OP_CONTINUE,
FLOW_OP_DISCARD FLOW_OP_DISCARD
}; };
enum ArgumentQualifier { enum ArgumentQualifier {
ARGUMENT_QUALIFIER_IN, ARGUMENT_QUALIFIER_IN,
ARGUMENT_QUALIFIER_OUT, ARGUMENT_QUALIFIER_OUT,
ARGUMENT_QUALIFIER_INOUT, ARGUMENT_QUALIFIER_INOUT,
}; };
struct Node { struct Node {
Node *next; Node *next;
enum Type { enum Type {
@ -296,7 +292,9 @@ public:
Type type; Type type;
virtual DataType get_datatype() const { return TYPE_VOID; } virtual DataType get_datatype() const { return TYPE_VOID; }
Node(Type t) :
next(NULL),
type(t) {}
virtual ~Node() {} virtual ~Node() {}
}; };
@ -311,18 +309,17 @@ public:
Node *nodes; Node *nodes;
struct OperatorNode : public Node { struct OperatorNode : public Node {
DataType return_cache; DataType return_cache;
DataPrecision return_precision_cache; DataPrecision return_precision_cache;
Operator op; Operator op;
Vector<Node *> arguments; Vector<Node *> arguments;
virtual DataType get_datatype() const { return return_cache; } virtual DataType get_datatype() const { return return_cache; }
OperatorNode() { OperatorNode() :
type = TYPE_OPERATOR; Node(TYPE_OPERATOR),
return_cache = TYPE_VOID; return_cache(TYPE_VOID),
return_precision_cache = PRECISION_DEFAULT; return_precision_cache(PRECISION_DEFAULT),
} op(OP_EQUAL) {}
}; };
struct VariableNode : public Node { struct VariableNode : public Node {
@ -330,20 +327,16 @@ public:
StringName name; StringName name;
virtual DataType get_datatype() const { return datatype_cache; } virtual DataType get_datatype() const { return datatype_cache; }
VariableNode() { VariableNode() :
Node(TYPE_VARIABLE),
type = TYPE_VARIABLE; datatype_cache(TYPE_VOID) {}
datatype_cache = TYPE_VOID;
}
}; };
struct VariableDeclarationNode : public Node { struct VariableDeclarationNode : public Node {
DataPrecision precision; DataPrecision precision;
DataType datatype; DataType datatype;
struct Declaration { struct Declaration {
StringName name; StringName name;
Node *initializer; Node *initializer;
}; };
@ -351,13 +344,13 @@ public:
Vector<Declaration> declarations; Vector<Declaration> declarations;
virtual DataType get_datatype() const { return datatype; } virtual DataType get_datatype() const { return datatype; }
VariableDeclarationNode() { VariableDeclarationNode() :
type = TYPE_VARIABLE_DECLARATION; Node(TYPE_VARIABLE_DECLARATION),
} precision(PRECISION_DEFAULT),
datatype(TYPE_VOID) {}
}; };
struct ConstantNode : public Node { struct ConstantNode : public Node {
DataType datatype; DataType datatype;
union Value { union Value {
@ -370,7 +363,9 @@ public:
Vector<Value> values; Vector<Value> values;
virtual DataType get_datatype() const { return datatype; } virtual DataType get_datatype() const { return datatype; }
ConstantNode() { type = TYPE_CONSTANT; } ConstantNode() :
Node(TYPE_CONSTANT),
datatype(TYPE_VOID) {}
}; };
struct FunctionNode; struct FunctionNode;
@ -388,39 +383,41 @@ public:
Map<StringName, Variable> variables; Map<StringName, Variable> variables;
List<Node *> statements; List<Node *> statements;
bool single_statement; bool single_statement;
BlockNode() {
type = TYPE_BLOCK; BlockNode() :
parent_block = NULL; Node(TYPE_BLOCK),
parent_function = NULL; parent_function(NULL),
single_statement = false; parent_block(NULL),
} single_statement(false) {}
}; };
struct ControlFlowNode : public Node { struct ControlFlowNode : public Node {
FlowOperation flow_op; FlowOperation flow_op;
Vector<Node *> expressions; Vector<Node *> expressions;
Vector<BlockNode *> blocks; Vector<BlockNode *> blocks;
ControlFlowNode() {
type = TYPE_CONTROL_FLOW; ControlFlowNode() :
flow_op = FLOW_OP_IF; Node(TYPE_CONTROL_FLOW),
} flow_op(FLOW_OP_IF) {}
}; };
struct MemberNode : public Node { struct MemberNode : public Node {
DataType basetype; DataType basetype;
DataType datatype; DataType datatype;
StringName name; StringName name;
Node *owner; Node *owner;
virtual DataType get_datatype() const { return datatype; } virtual DataType get_datatype() const { return datatype; }
MemberNode() { type = TYPE_MEMBER; }
MemberNode() :
Node(TYPE_MEMBER),
basetype(TYPE_VOID),
datatype(TYPE_VOID),
owner(NULL) {}
}; };
struct FunctionNode : public Node { struct FunctionNode : public Node {
struct Argument { struct Argument {
ArgumentQualifier qualifier; ArgumentQualifier qualifier;
StringName name; StringName name;
DataType type; DataType type;
@ -434,16 +431,15 @@ public:
BlockNode *body; BlockNode *body;
bool can_discard; bool can_discard;
FunctionNode() { FunctionNode() :
type = TYPE_FUNCTION; Node(TYPE_FUNCTION),
return_type = TYPE_VOID; return_type(TYPE_VOID),
return_precision = PRECISION_DEFAULT; return_precision(PRECISION_DEFAULT),
can_discard = false; body(NULL),
} can_discard(false) {}
}; };
struct ShaderNode : public Node { struct ShaderNode : public Node {
struct Function { struct Function {
StringName name; StringName name;
FunctionNode *function; FunctionNode *function;
@ -454,7 +450,12 @@ public:
struct Varying { struct Varying {
DataType type; DataType type;
DataInterpolation interpolation; DataInterpolation interpolation;
DataPrecision precission; DataPrecision precision;
Varying() :
type(TYPE_VOID),
interpolation(INTERPOLATION_FLAT),
precision(PRECISION_DEFAULT) {}
}; };
struct Uniform { struct Uniform {
@ -474,16 +475,20 @@ public:
int order; int order;
int texture_order; int texture_order;
DataType type; DataType type;
DataPrecision precission; DataPrecision precision;
Vector<ConstantNode::Value> default_value; Vector<ConstantNode::Value> default_value;
Hint hint; Hint hint;
float hint_range[3]; float hint_range[3];
Uniform() { Uniform() :
hint = HINT_NONE; order(0),
hint_range[0] = 0; texture_order(0),
hint_range[1] = 1; type(TYPE_VOID),
hint_range[2] = 0.001; precision(PRECISION_DEFAULT),
hint(HINT_NONE) {
hint_range[0] = 0.0f;
hint_range[1] = 1.0f;
hint_range[2] = 0.001f;
} }
}; };
@ -493,11 +498,11 @@ public:
Vector<Function> functions; Vector<Function> functions;
ShaderNode() { type = TYPE_SHADER; } ShaderNode() :
Node(TYPE_SHADER) {}
}; };
struct Expression { struct Expression {
bool is_op; bool is_op;
union { union {
Operator op; Operator op;
@ -506,7 +511,6 @@ public:
}; };
struct VarInfo { struct VarInfo {
StringName name; StringName name;
DataType type; DataType type;
}; };
@ -522,7 +526,6 @@ public:
}; };
struct Token { struct Token {
TokenType type; TokenType type;
StringName text; StringName text;
double constant; double constant;
@ -556,11 +559,14 @@ public:
struct BuiltInInfo { struct BuiltInInfo {
DataType type; DataType type;
bool constant; bool constant;
BuiltInInfo() {}
BuiltInInfo(DataType p_type, bool p_constant = false) { BuiltInInfo() :
type = p_type; type(TYPE_VOID),
constant = p_constant; constant(false) {}
}
BuiltInInfo(DataType p_type, bool p_constant = false) :
type(p_type),
constant(p_constant) {}
}; };
struct FunctionInfo { struct FunctionInfo {
@ -573,6 +579,7 @@ private:
TokenType token; TokenType token;
const char *text; const char *text;
}; };
static const KeyWord keyword_list[]; static const KeyWord keyword_list[];
bool error_set; bool error_set;
@ -628,14 +635,11 @@ private:
}; };
bool _find_identifier(const BlockNode *p_block, const Map<StringName, BuiltInInfo> &p_builtin_types, const StringName &p_identifier, DataType *r_data_type = NULL, IdentifierType *r_type = NULL); bool _find_identifier(const BlockNode *p_block, const Map<StringName, BuiltInInfo> &p_builtin_types, const StringName &p_identifier, DataType *r_data_type = NULL, IdentifierType *r_type = NULL);
bool _is_operator_assign(Operator p_op) const; bool _is_operator_assign(Operator p_op) const;
bool _validate_assign(Node *p_node, const Map<StringName, BuiltInInfo> &p_builtin_types, String *r_message = NULL); bool _validate_assign(Node *p_node, const Map<StringName, BuiltInInfo> &p_builtin_types, String *r_message = NULL);
bool _validate_operator(OperatorNode *p_op, DataType *r_ret_type = NULL); bool _validate_operator(OperatorNode *p_op, DataType *r_ret_type = NULL);
struct BuiltinFuncDef { struct BuiltinFuncDef {
enum { MAX_ARGS = 5 }; enum { MAX_ARGS = 5 };
const char *name; const char *name;
DataType rettype; DataType rettype;
@ -643,7 +647,6 @@ private:
}; };
struct BuiltinFuncOutArgs { //arguments used as out in built in funcions struct BuiltinFuncOutArgs { //arguments used as out in built in funcions
const char *name; const char *name;
int argument; int argument;
}; };
@ -656,20 +659,17 @@ private:
int completion_argument; int completion_argument;
bool _get_completable_identifier(BlockNode *p_block, CompletionType p_type, StringName &identifier); bool _get_completable_identifier(BlockNode *p_block, CompletionType p_type, StringName &identifier);
static const BuiltinFuncDef builtin_func_defs[]; static const BuiltinFuncDef builtin_func_defs[];
static const BuiltinFuncOutArgs builtin_func_out_args[]; static const BuiltinFuncOutArgs builtin_func_out_args[];
bool _validate_function_call(BlockNode *p_block, OperatorNode *p_func, DataType *r_ret_type);
bool _validate_function_call(BlockNode *p_block, OperatorNode *p_func, DataType *r_ret_type);
bool _parse_function_arguments(BlockNode *p_block, const Map<StringName, BuiltInInfo> &p_builtin_types, OperatorNode *p_func, int *r_complete_arg = NULL); bool _parse_function_arguments(BlockNode *p_block, const Map<StringName, BuiltInInfo> &p_builtin_types, OperatorNode *p_func, int *r_complete_arg = NULL);
Node *_parse_expression(BlockNode *p_block, const Map<StringName, BuiltInInfo> &p_builtin_types); Node *_parse_expression(BlockNode *p_block, const Map<StringName, BuiltInInfo> &p_builtin_types);
ShaderLanguage::Node *_reduce_expression(BlockNode *p_block, ShaderLanguage::Node *p_node); ShaderLanguage::Node *_reduce_expression(BlockNode *p_block, ShaderLanguage::Node *p_node);
Node *_parse_and_reduce_expression(BlockNode *p_block, const Map<StringName, BuiltInInfo> &p_builtin_types); Node *_parse_and_reduce_expression(BlockNode *p_block, const Map<StringName, BuiltInInfo> &p_builtin_types);
Error _parse_block(BlockNode *p_block, const Map<StringName, BuiltInInfo> &p_builtin_types, bool p_just_one = false, bool p_can_break = false, bool p_can_continue = false); Error _parse_block(BlockNode *p_block, const Map<StringName, BuiltInInfo> &p_builtin_types, bool p_just_one = false, bool p_can_break = false, bool p_can_continue = false);
Error _parse_shader(const Map<StringName, FunctionInfo> &p_functions, const Vector<StringName> &p_render_modes, const Set<String> &p_shader_types); Error _parse_shader(const Map<StringName, FunctionInfo> &p_functions, const Vector<StringName> &p_render_modes, const Set<String> &p_shader_types);
public: public: